"... используя rambda"
Вот один как вы можете это сделать - есть множество других способов ...
const a =
'abcdefg'
const b =
'abcxyzg'
const countEqualChars = (a, b) =>
R.sum(R.zipWith(R.equals, a, b))
countEqualChars(a,b)
// 4
Но ...
Это, по сути, неправильный путь для подхода к функциональному программированию. Забудьте Rambda, пока у вас не будет здравого смысла, как рассуждать о программах функционально. Вы никогда не сможете оценить удобство Рамбы, если вы не знаете, как все работает на фундаментальном уровне.
Начать изучение рекурсии как альтернативы for/while
Петли. Там нет ничего плохого с петлями, но рекурсия позволит вам выразить вещи более хорошим способом иногда ...
const a =
'abcdefg'
const b =
'abcxyzg'
const countEqualChars = ([ x, ...xs ], [ y, ...ys ]) =>
{
if (x === undefined || y === undefined)
return 0
else if (x === y)
return 1 + countEqualChars (xs, ys)
else
return countEqualChars (xs, ys)
}
console.log (countEqualChars (a, b))
// 4
Теперь мы видим, что эта функция делает совсем немного. Мы проверяем массивы по одному элементу за раз, сравниваем и подсчитываем. Возможно, мы могли бы разбить это на некоторые отдельные задачи, чтобы наша функция была немного более удобной с течением времени. Давайте начнем с функцией, которая позволяет нам паре равные показатели двух массивов ...
const zip = ([ x, ...xs ], [ y, ...ys ]) =>
x === undefined && y === undefined
? []
: [ [ x, y ] ] .concat (zip (xs, ys))
console.log (zip ([ 1, 2, 3 ], [ 'a', 'b', 'c' ]))
// [ [ 1, 'a' ]
// , [ 2, 'b' ]
// , [ 3, 'c' ]
// ]
Далее, можно использовать встроенный в filter
функции, чтобы сделать новый массив, содержащий только вещи, которые мы хотим
const xs =
[ 1, 1, 2, 2, 3, 3, 4, 4 ]
const justThrees =
xs.filter (x => x === 3)
console.log (justThrees)
// [ 3, 3 ]
Сочетание этих zip
и filter
страты, мы можем паре каждый индекс из строки, а затем удалить пары, которые не соответствуют ...
const zip = ([ x, ...xs ], [ y, ...ys ]) =>
x === undefined && y === undefined
? []
: [ [ x, y ] ] .concat (zip (xs, ys))
}
const eq = (x, y) =>
x === y
const apply = f => xs =>
f (...xs)
const a =
'abcdefg'
const b =
'abcxyzgh'
const matches =
zip (a, b) .filter (apply (eq))
console.log (matches)
// [ [ 'a', 'a' ]
// , [ 'b', 'b' ]
// , [ 'c', 'c' ]
// , [ 'g', 'g' ]
// ]
Теперь все, что осталось, подсчитывая совпадающие пары.Мы будем делать все это в функции тоже, так что вы можете повторно использовать его по мере необходимости
const zip = ([ x, ...xs ], [ y, ...ys ]) =>
x === undefined && y === undefined
? []
: [ [ x, y ] ] .concat (zip (xs, ys))
const eq = (x, y) =>
x === y
const apply = f => xs =>
f (...xs)
const countEqualChars = (a, b) =>
zip (a, b)
.filter (apply (eq))
.length
console.log (countEqualChars ('abcdefg', 'abcxyzgh'))
// 4
самое главное ...
Вы увидите, что решение, полученное нами вручную, немного разных, чем тот, который мы использовали с Rambda. Это потому, что программирование не является волшебным, и вы будете изобретать много своих собственных инструментов, прежде чем осознавать, какие другие инструменты существуют или понимать, что они делают.
Есть сотни способов решить проблему, которую я только что сделал, и есть компромиссы, которые я рассматривал при каждом выборе, который я сделал. Ваша цель состоит в том, чтобы превратить вашу программу в ее составные части и узнать компромиссы с течением времени.
Сравните это с тем, чтобы понять, почему какая-то функция существует в какой-то библиотеке, чтобы вы могли угадать, где ее использовать ... Вы получите хорошее функциональное программирование, сделав это, а не путем копирования/вставки умных людей Rambda one -liners. Как только вы поймете , почемуequals
, zipWith
и sum
существуют, вы будете знать, когда их использовать.
Позволь мне знать, если я могу помочь прояснить что-нибудь еще^_^
Я не мог бы желать более полной лучшей мысли ответ. Большое спасибо ^^. –