我有一个像这样的 JSON 嵌套对象树。 如何通过将 ID 值传递给函数来获取指定的对象。 (ID是所有嵌套对象中的key)
我尝试使用递归和 JSON.stringify().findObject() 但不知何故它们不起作用。
{
"id": "A",
"name": "Item A",
"child": [
{
"id": "B",
"name": "Item B",
"child": [
{
"id": "C",
"name": "Item C"
"child": []
}
]
},
{
"id": "D",
"name": "Item D",
"child": []
}
]
}
//Calling like this
var result = findObject("C");
然后console.log(result);
应该是
{
"id": "C",
"name": "Item C"
"child": []
}
最佳答案
Nick Parsons 的回答很棒,代码写得很好,解释也很好。
但我认为有可能把它写得更通用、更简单。
虽然这里的要求是通过id
进行搜索,但我们可以很容易地想象出我们想要匹配的各种其他方式。我们可以编写一个采用任意谓词的通用版本,然后使用一个简单的函数对其进行配置,而不是试图预测所有这些。
这是一种方法:
const deepFind = (pred) => ([x, ...xs] = []) =>
x && (pred (x) ? x : deepFind (pred) (x.child) || deepFind (pred) (xs))
const findById = (id) => (obj) =>
deepFind ((o) => o.id == id) ([obj])
const input = {id: "A", name: "Item A", child: [{id: "B", name: "Item B", child: [{id: "C", name: "Item C", child: []}]}, {id: "D", name: "Item D", child: []}]};
console .log ('C:', findById ('C') (input)) //~> {id: "C", name: "Item C", child: []}
console .log ('X:', findById ('X') (input)) //~> undefined
deepFind
接受谓词函数并返回一个函数,该函数接受数组并在深度优先搜索时返回第一个匹配项(在 node -> node.child
树上) 匹配谓词。
我们用 findById
包装它,它接受一个目标 id,并返回一个函数,该函数接受一个输入对象,将该对象包装在一个数组中,并调用 deepFind
用于测试 id 是否与目标和该数组匹配的谓词。
我们可以通过向 deepFind 添加另一个初始参数来告诉我们树的结构,从而轻松地使其更通用。 (node -> node.children
可能更常见。)但这是另一天的任务。
deepFind
可能有一个稍微密集的实现。它可以用多种方式编写,如果其中一种对您更有意义的话:
const deepFind = (pred) => (xs) => {
for (let x of xs) {
if (pred (x)) {return x}
return deepFind (pred) (x .child || [])
}
}
或
const deepFind = (pred) => ([x, ...xs]) =>
x == undefined
? undefined
: pred (x)
? x
: deepFind (pred) (x.child || []) || deepFind (pred) (xs)
或在 traverse
生成器函数之上:
function * traverse (xs = []) {
for (let x of xs) {
yield x;
yield * traverse (x.child || [])
}
}
const deepFind = (pred) => (obj) => {
for (let node of traverse ([obj])) {
if (pred (node)) {return node}
}
}
我们还可以找到更多。
关于javascript - 在 JavaScript 中通过键从嵌套对象数组中查找对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68559392/