通过ID的数组路径获取深度嵌套的对象

时间:2020-07-21 14:24:09

标签: json

我有这个JSON数据,其中包含带选项的问题以及嵌套在其中的问题。因此,用户选择一个答案,然后根据该答案选择下一个问题,依此类推....我有一个数组,该数组本质上是我要查找的特定问题对象的(标识)路径。如何使用我的react组件中的路径数组到达那个对象?

parallel
path = ["525289", "128886", "123456", "7547", "35735"] 

3 个答案:

答案 0 :(得分:0)

如果您愿意使用(小型)库,则可以使用类似自己的J-Path,它允许您使用XPath(第二个)查询和遍历对象(第一个参数),即通常用于查询XML。

let item = jpath(object, 'question[id="525289"]/options/item[id="128886"]/question[id="123456"]/options/item[id="7547"]/question[id="35735"]');

或者,更简单地说,我们可以使用最终ID直接进入目标:

let item = jpath(object, '//question[id="35735"]');

如果您不需要库,则需要手动浏览ID,并使用while循环,直到找到所需的数据项为止。

答案 1 :(得分:0)

尽管示例中存在一些不一致之处,但是可以使用reduce函数使用与您提供的路径相似(尽管不太相似)的路径来完成。例如,问题与选项之间似乎具有1:1的关系,因此似乎不需要对遍历进行过滤?

或者,如Mitya所述,您可以使用JSON查询库。这些是更通用的用途,因此比具有数据结构上下文知识的定制解决方案更为冗长。

我在这里使用了一个更简单的递归父子模型:

let data = [
    {
        id: "123",
        children: [
            {
                id: "456A",
                title: "xyz",
                children: [
                    {
                        id: "789AA",
                        message: "Foo"
                    },
                    {
                        id: "789AB",
                        message: "Bar"
                    }
                ]
            },
            {
                id: "456B",
                title: "abc",
                children: [
                    {
                        id: "789BA",
                        message: "Hello"
                    },
                    {
                        id: "789BB",
                        message: "World!"
                    }
                ]
            }
        ]
    }
];
let path1 = ["123", "456A", "789AA"];
let path2 = ["123", "456C", "789CA"]; // Invalid as 456C isn't a valid item at this point in the tree
let path3 = ["123", "456B", "789BB"];
function select(path, data) {
    return path.reduce((acc, v) => acc && acc.children.find(c => c.id === v), {children: data});
}
console.log(select(path1, data));
console.log(select(path2, data));
console.log(select(path3, data));

输出:

{ id: '789AA', message: 'Foo' }
undefined
{ id: '789BB', message: 'World!' }

答案 2 :(得分:0)

我认为您对这个问题的态度是错误的。我认为更好的方法是将每个问题分别定义为它们自己的对象,然后使用嵌套对象数组。

var questionId1 = {}
var questionId2 = {}
var questionId3 = {}
var questionId4 = {}
var questionId5 = {}

questionId1.options = [questionId2, questionId3]
questionId2.options = [questionId4]
questionId4.options = [questionId5] 

以这种方式闲逛会使路径的想法过时。您只需要当前问题的名称即可显示选项。选择下一个问题时,父级不再重要,只有子级才重要。

不过,如果由于某种原因而无法使用此方法,则可以使用.表示法访问对象内部的嵌套元素。在这种情况下,听起来您正在寻找每个元素的ID,并想要该元素的options对象。假设您需要遍历用户路径并在路径末尾返回选项的选项,则将需要大量嵌套的if来确保存在某些属性并且它们是不为空,并循环进入数组。

Here's a fiddle显示了该方法。