Я считаю, что я изучил некоторые / многие / большинство основных концепций, лежащих в основе функционального программирования в JavaScript. Однако у меня возникают проблемы с чтением функционального кода, даже кода, который я написал, и мне интересно, кто-нибудь может дать мне какие-нибудь советы, советы, рекомендации, терминологию и т. Д., Которые могут помочь.
Возьми код ниже. Я написал этот код. Он призван установить процентное сходство между двумя объектами, скажем, {a:1, b:2, c:3, d:3}
и {a:1, b:1, e:2, f:2, g:3, h:5}
. Я создал код в ответ на этот вопрос о переполнении стека . Поскольку я точно не знал, о каком процентном сходстве спрашивал плакат, я предоставил четыре разных типа:
- процент ключей в первом объекте, который можно найти во втором,
- процент значений в первом объекте, который можно найти во втором, включая дубликаты,
- процент значений в 1-м объекте, который можно найти во 2-м, без дубликатов, и
- процент пар {ключ: значение} в 1-м объекте, который можно найти во 2-м объекте.
Я начал с достаточно императивного кода, но быстро понял, что эта проблема хорошо подходит для функционального программирования. В частности, я понял, что если бы я мог извлечь функцию или три для каждой из четырех вышеупомянутых стратегий, которые определяли тип функции, которую я хотел сравнить (например, ключи или значения и т. Д.), То я мог бы быть возможность сократить (простите за игру слов) остальную часть кода на повторяемые единицы. Вы знаете, сохраняя это СУХОЙ. Поэтому я переключился на функциональное программирование. Я очень горжусь результатом, я думаю, что он достаточно элегантный, и я понимаю, что хорошо справился.
Тем не менее, даже написав код сам и понимая каждую его часть во время конструирования, когда я теперь оглядываюсь на него, я по-прежнему несколько удивлен, как читать какую-то конкретную строку, так и как "Грок", что на самом деле делает какая-то конкретная половина строки кода. Я обнаружил, что делаю мысленные стрелки, чтобы соединить разные части, которые быстро разлагаются в беспорядок спагетти.
Итак, может ли кто-нибудь сказать мне, как «читать» некоторые из более запутанных фрагментов кода таким образом, который является одновременно и кратким, и это способствует моему пониманию того, что я читаю? Я думаю, что части, которые меня больше всего привлекают, это те, у которых есть несколько жирных стрелок подряд и / или части, у которых есть несколько скобок подряд. Опять же, по своей сути, я могу со временем разобраться в логике, но (я надеюсь) есть лучший способ быстро и четко и прямо «взять на себя» линию функционального программирования на JavaScript.
Не стесняйтесь использовать любую строку кода снизу или даже другие примеры. Однако, если вы хотите, чтобы некоторые первоначальные предложения от меня, вот несколько. Начните с достаточно простого. С ближе к концу кода, есть такой , который передается в качестве параметра функции: obj => key => obj[key]
. Как читать и понимать это? Более длинный пример одну полной функции от около начала: const getXs = (obj, getX) => Object.keys(obj).map(key => getX(obj)(key));
. Последняя map
часть меня особенно привлекает.
Пожалуйста, обратите внимание, что в данный момент я не ищу ссылки на Haskell или символьную абстрактную нотацию или основы каррирования и т. Д. То, что я ищу, это английские предложения, которые я могу молча произносить, глядя на строку кода. Если у вас есть ссылки, которые конкретно касаются именно этого, прекрасно, но я также не ищу ответы, в которых говорится, что я должен пойти и прочесть некоторые основные учебники. Я сделал это, и я получил (по крайней мере, значительное количество) логику. Также обратите внимание, что мне не нужны исчерпывающие ответы (хотя такие попытки приветствуются): приветствуются даже короткие ответы, которые обеспечивают элегантный способ чтения одной конкретной строки кода, который в противном случае был бы проблематичным.
Я предполагаю, что часть этого вопроса такова: могу ли я читать функциональный код линейно, знаете ли, слева направо и сверху вниз? Или кто-то в значительной степени вынужден создавать мысленную картину спагетти-подобной проводки на странице кода, которая определенно не линейна? И если это нужно сделать, нам все равно нужно прочитать код, так как же взять линейный текст и связать спагетти?
Любые советы будут оценены.
const obj1 = { a:1, b:2, c:3, d:3 };
const obj2 = { a:1, b:1, e:2, f:2, g:3, h:5 };
// x or X is key or value or key/value pair
const getXs = (obj, getX) =>
Object.keys(obj).map(key => getX(obj)(key));
const getPctSameXs = (getX, filter = vals => vals) =>
(objA, objB) =>
filter(getXs(objB, getX))
.reduce(
(numSame, x) =>
getXs(objA, getX).indexOf(x) > -1 ? numSame + 1 : numSame,
0
) / Object.keys(objA).length * 100;
const pctSameKeys = getPctSameXs(obj => key => key);
const pctSameValsDups = getPctSameXs(obj => key => obj[key]);
const pctSameValsNoDups = getPctSameXs(obj => key => obj[key], vals => [...new Set(vals)]);
const pctSameProps = getPctSameXs(obj => key => JSON.stringify( {[key]: obj[key]} ));
console.log('obj1:', JSON.stringify(obj1));
console.log('obj2:', JSON.stringify(obj2));
console.log('% same keys: ', pctSameKeys (obj1, obj2));
console.log('% same values, incl duplicates:', pctSameValsDups (obj1, obj2));
console.log('% same values, no duplicates: ', pctSameValsNoDups(obj1, obj2));
console.log('% same properties (k/v pairs): ', pctSameProps (obj1, obj2));
// output:
// obj1: {"a":1,"b":2,"c":3,"d":3}
// obj2: {"a":1,"b":1,"e":2,"f":2,"g":3,"h":5}
// % same keys: 50
// % same values, incl duplicates: 125
// % same values, no duplicates: 75
// % same properties (k/v pairs): 25