gpt4 book ai didi

javascript - 给定数组提取对象值的功能方法

转载 作者:行者123 更新时间:2023-12-03 12:36:59 25 4
gpt4 key购买 nike

我有一个键值对对象数组,如下所示:

var d = [{'name':'a', 'value':1}, {'name':'b', 'value':2}, {'name':'c', 'value':3}, {'name':'d', 'value':4}, {'name':'e', 'value':5}, {'name':'f', 'value':6}]

和一个数组
var a = ['a','e']

我如何编写一个提取值的函数,本质上我想要的结果是
[{'name':'a', 'value':1},{'name':'e', 'value':5} ]

我想以纯函数方式编写它,而不是使用 for , while循环,或 filter功能。我想知道有没有合适有效的方法?递归是正确的方法吗?我愿意使用 lodash , ramda或任何其他 FP 包。

最佳答案

Array.prototype.map 和 Array.prototype.find

看起来你对实现细节很固执,但我敢肯定你不知道为什么。 for 没有问题或 whilefilter .在这篇文章的结尾,我不希望你相信我,而是希望你知道这是真的。

您可以使用 map 轻松解决此问题。和 find – 出于所有意图和目的,如何 mapfind实现对你来说是个谜。他们是否使用 for 没关系循环甚至是 GOTO因为大声哭泣。对你来说重要的是你能以一种实用的方式表达你的问题。
mapfind是谦逊的 JavaScript 函数式程序员的完美伴侣......

var d = [{'name':'a', 'value':1}, {'name':'b', 'value':2}, {'name':'c', 'value':3}, {'name':'d', 'value':4}, {'name':'e', 'value':5}, {'name':'f', 'value':6}]

var a = ['a','e']

var result = a.map(x => d.find(y => y.name === x))

console.log(result)
// [ { name: 'a', value: 1 },
// { name: 'e', value: 5 } ]



泛型函数促进代码重用

使用一些泛型函数,我们可以用更可重用的方式表达解决方案

var data = [{'name':'a', 'value':1}, {'name':'b', 'value':2}, {'name':'c', 'value':3}, {'name':'d', 'value':4}, {'name':'e', 'value':5}, {'name':'f', 'value':6}]

const findBy = k => xs => v =>
xs.find(x => x[k] === v)

const findAllBy = k => xs => vs =>
vs.map(findBy(k)(xs))

console.log(findAllBy ('name') (data) (['a', 'e']))
// [ { name: 'a', value: 1 },
// { name: 'e', value: 5 } ]



为什么固执没有帮助

如果您想看看这是如何在不依赖任何 for 的情况下完成的, while , filter , map , 或 find ...

var data = [{'name':'a', 'value':1}, {'name':'b', 'value':2}, {'name':'c', 'value':3}, {'name':'d', 'value':4}, {'name':'e', 'value':5}, {'name':'f', 'value':6}]

const main = ([x,...xs]) => {
const aux = ([y,...ys]) => {
if (y === undefined)
return null
else if (y.name === x)
return y
else
return aux (ys)
}
if (x === undefined)
return []
else
return [aux(data), ...main(xs)]
}

console.log(main(['a', 'e']))
// [ { name: 'a', value: 1 },
// { name: 'e', value: 5 } ]


很痛苦吧?并且该代码的执行情况比此处仍然具有 length 等依赖项的其他答案要少。 , indexOf , slice或整个 lodash 库。

所以真的这样做是没有意义的。在这个示例中编码了大量有用的通用函数,我们希望在其他地方使用它们。这就是为什么像 map 这样的函数, reduce , filter , 和 find一开始就存在—— for 也是如此和 while .

每次我想遍历一个数组,或者过滤一个数组,或者在一个数组中查找一个元素时,我都不想手动完成。我使用函数的原因是我不必重复自己……永远。

好奇心

所以也许你对 map 没意见+ find上面的解决方案,但是您也很好奇,如果您还没有它们可供您使用,您将如何自己实现它们 - 以下只是您可以实现这些功能中的任何一个的无数方法中的两种。

var data = [{'name':'a', 'value':1}, {'name':'b', 'value':2}, {'name':'c', 'value':3}, {'name':'d', 'value':4}, {'name':'e', 'value':5}, {'name':'f', 'value':6}]

const find = f => ([x,...xs]) =>
x === undefined ? null :
f(x) === true ? x : find (f) (xs)

const map = f => ([x,...xs]) =>
x === undefined ? [] : [f(x), ...map(f)(xs)]

const main =
map (x => find (y => y.name === x) (data))

console.log(main(['a', 'e']))
// [ { name: 'a', value: 1 },
// { name: 'e', value: 5 } ]



递归吸收 JavaScript

很多人不知道 JavaScript 中的递归是它实际上不是很好。我们 promise 在 ES6 中消除尾调用,但当前的 JavaScript 实现还没有真正支持它。这意味着您编写的任何递归函数(除非您将其蹦床)都存在堆栈溢出的潜在风险。

这意味着使用 for 实现功能接口(interface)和 while好多了。

下面,我们重新实现 mapfind但是这次我们通过避免堆栈溢出的风险以一种聪明的方式做到这一点。请注意,它对生成的代码并没有真正的影响。我们仍然可以与 map 互动和 find以一种很好的、​​实用的方式——它们都是引用透明的

特别注意 main功能 - 它与上面的示例完全没有变化。我们的“丑” whilefor循环作为实现细节被巧妙地隐藏起来,最终用户并不聪明。

var data = [{'name':'a', 'value':1}, {'name':'b', 'value':2}, {'name':'c', 'value':3}, {'name':'d', 'value':4}, {'name':'e', 'value':5}, {'name':'f', 'value':6}]

const find = f => xs => {
for (let x of xs)
if (f(x) === true)
return x
return null
}

const map = f => xs => {
const acc = Array(xs.length)
for (let [i,x] of xs.entries())
acc[i] = f(x)
return acc
}

const main =
map (x => find (y => y.name === x) (data))

console.log(main(['a', 'e']))
// [ { name: 'a', value: 1 },
// { name: 'e', value: 5 } ]

关于javascript - 给定数组提取对象值的功能方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43060236/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com