我相信我已经学到了JavaScript中的一些/许多/大多数基本的函数式编程基础。但是,我在阅读功能代码(甚至是我编写的代码)时遇到了麻烦,并且想知道是否有人可以给我提供任何可以提供帮助的指针,技巧,最佳实践,术语等。
使用下面的代码。我写了这段代码。它旨在在say {a:1, b:2, c:3, d:3}
和之间分配两个对象之间的相似度百分比{a:1, b:1, e:2, f:2, g:3, h:5}
。我针对Stack Overflow上的这个问题生成了代码。因为我不确定海报要问的相似度百分比,所以我提供了四种不同的相似度:
- 在第二个对象中可以找到的第一个对象中键的百分比,
- 在第二个对象中可以找到的第一个对象中值的百分比,包括重复项,
- 在第二个对象中可以找到的第一个对象中的值的百分比,不允许重复,并且
- 在第一个对象中可以找到的第一个对象中{key:value}对的百分比。
我以合理的命令性代码开始,但是很快意识到这是一个非常适合函数式编程的问题。尤其是,我意识到,如果我可以针对上述四种策略中的每一种提取出一个或三个函数,这些策略定义了我要比较的特征类型(例如键或值等),那么我可能会能够将其余的代码减少(请原谅文字的打法)为可重复的单元。要知道,保持干燥。所以我改用函数式编程。我为结果感到非常自豪,我认为它相当优雅,并且我认为自己做得很好。
但是,即使我自己编写了代码并在构造过程中理解了代码的每个部分,当我现在回头看时,我仍然对如何读取任何特定的半行以及如何读取都感到困惑。 “抱怨”任何特定的半行代码实际上在做什么。我发现自己制作了一些易用的箭头,将不同的部分连接起来,这些部分很快就会变成一团意大利面。
因此,谁能告诉我如何以简洁明了的方式“阅读”一些更复杂的代码,这有助于我对正在阅读的内容的理解?我猜最吸引我的部分是连续有几个粗箭头的部分和/或连续有多个括号的部分。同样,在它们的核心处,我最终可以弄清楚逻辑,但是(我希望)有一种更好的方法可以快速,清晰,直接地“接受”一系列功能性JavaScript编程。
随意使用下面的任何代码行,甚至其他示例。但是,如果您需要我的一些初步建议,以下是一些建议。从一个相当简单的开始。在代码的末尾,有一个作为参数传递给函数:obj => key => obj[key]
。一个人如何阅读和理解呢?较长的示例是从一开始就提供的一项完整功能:const getXs = (obj, getX) => Object.keys(obj).map(key => getX(obj)(key));
。最后map
一部分让我特别感兴趣。
请注意,目前我不是在寻找Haskell或符号抽象符号或currying的基础知识等的参考。我要寻找的是英文句子,我可以在看着一行代码时默默地开口。如果您有专门解决此问题的参考书,那很好,但是我也没有在寻找答案,我应该去读一些基础教科书。我已经做到了,我得到了(至少是很大一部分)逻辑。还要注意,我不需要详尽的答案(尽管可以尝试这样的尝试):即使是简短的答案,也提供了一种优雅的方式来读取一行特定的否则麻烦的代码,将不胜感激。
我想这个问题的一部分:灿我甚至线性阅读的功能代码,你就知道,左到右,上到下的?还是被迫在绝对不是线性的代码页上创建意粉般布线的心理图景?而且,如果必须这样做,我们仍然必须阅读代码,那么如何获取线性文本并连接意大利面呢?
任何提示将不胜感激。
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