首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用索引路径查找深度嵌套对象并进行更新的最有效方法

使用索引路径查找深度嵌套对象并进行更新的最有效方法
EN

Stack Overflow用户
提问于 2022-09-21 22:51:52
回答 2查看 55关注 0票数 3

我有一系列的树结构。我需要能够使用索引路径找到对象并更新切换布尔值。我能够使用索引路径更新切换,但如果向树中添加了更多的节点级别,则需要更新此逻辑。我如何使它成为通用的,这样即使更改了treeData,我的代码仍然可以工作。如果它在索引路径中而不是在其中一条路径中,那么如果我可以设置所有其他节点false,那就太好了。

代码语言:javascript
复制
treeData = [{
    name: 'Infiniti',
    toggle: false,
    children: [{
        name: 'G50',
        toggle: false,
        children: [{
            name: 'Pure AWD',
            toggle: false
          },
          {
            name: 'Luxe',
            toggle: false
          },
        ],
      },
      {
        name: 'QX50',
        toggle: false,
        children: [{
            name: 'Pure AWD',
            toggle: false
          },
          {
            name: 'Luxe',
            toggle: false
          },
        ],
      },
    ],
  },
  {
    name: 'BMW',
    toggle: false,
    children: [{
        name: '2 Series',
        toggle: false,
        children: [{
            name: 'Coupé',
            toggle: false
          },
          {
            name: 'Gran Coupé',
            toggle: false
          },
        ],
      },
      {
        name: '3 Series',
        toggle: false,
        children: [{
            name: 'Sedan',
            toggle: false
          },
          {
            name: 'PHEV',
            toggle: false
          },
        ],
      },
    ],
  },
];

indexPathArray = ["0/0/1", "1/0/0"]

for (const index of indexPathArray) {
  const indexArray = index.split('/')
  for (let i = 0; i < indexArray.length; i++) {
    if (i === 0) {
      treeData[indexArray[0]].toggle = true;
    }
    if (i === 1) {
      treeData[indexArray[0]].children[indexArray[1]].toggle = true;
    }
    if (i === 2) {
      treeData[indexArray[0]].children[indexArray[1]].children[indexArray[2]].toggle = true;
    }
  }
}

console.log(treeData);

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-09-21 23:47:27

您可以使用以下代码来实现它:

代码语言:javascript
复制
for (let path of indexPathArray) {
  let currentNode = { children: treeData };
  for (let i of path.split('/')) {
    currentNode = currentNode.children[i];
    currentNode.toggle = true;
  }
}

这里的想法是有一个临时变量currentNode,它包含树遍历的当前游标。

这将允许您从索引路径访问下一项,而无需编写整个路径。

一段片段:

代码语言:javascript
复制
treeData = [{
    name: 'Infiniti',
    toggle: false,
    children: [{
        name: 'G50',
        toggle: false,
        children: [{
            name: 'Pure AWD',
            toggle: false
          },
          {
            name: 'Luxe',
            toggle: false
          },
        ],
      },
      {
        name: 'QX50',
        toggle: false,
        children: [{
            name: 'Pure AWD',
            toggle: false
          },
          {
            name: 'Luxe',
            toggle: false
          },
        ],
      },
    ],
  },
  {
    name: 'BMW',
    toggle: false,
    children: [{
        name: '2 Series',
        toggle: false,
        children: [{
            name: 'Coupé',
            toggle: false
          },
          {
            name: 'Gran Coupé',
            toggle: false
          },
        ],
      },
      {
        name: '3 Series',
        toggle: false,
        children: [{
            name: 'Sedan',
            toggle: false
          },
          {
            name: 'PHEV',
            toggle: false
          },
        ],
      },
    ],
  },
];

indexPathArray = ["0/0/1", "1/0/0"]

for (let path of indexPathArray) {
  let currentNode = { children: treeData };
  for (let i of path.split('/')) {
    currentNode = currentNode.children[i];
    currentNode.toggle = true;
  }
}

console.log(treeData);

票数 1
EN

Stack Overflow用户

发布于 2022-09-21 23:48:03

递归

基本上,您一次进入一个级别,调用相同的函数,就好像内部节点是新的根节点一样。然后,当您到达搜索路径的末尾时,执行您想要的操作。

看起来可能是这样:

代码语言:javascript
复制
function togglePath(tree: Tree[], indexPath: string) {
  const [first, ...rest] = indexPath.split('/').map(n => parseInt(n))
  const children = tree[first]?.children

  if (children && rest.length > 0) {
    togglePath(children, rest.join('/'))
  } else {
    tree[first].toggle = true;
  }
}

这是一个递归函数,因为它调用自己。

每个级别检查一次,看看它是否在rest.length > 0中。如果只有一个索引路径,那么我们找到目标,进行切换。

如果我们需要进行更多的研究,那么从第一个索引中再次使用节点的子节点调用togglePath,并为下一个级别提供其余的索引。

这在任何级别都应该有效:

代码语言:javascript
复制
console.log(treeData[0].children?.[0].children?.[1].toggle) // false
togglePath(treeData, "0/0/1")
console.log(treeData[0].children?.[0].children?.[1].toggle) // true

console.log(treeData[0].children?.[1].toggle) // false
togglePath(treeData, "0/1")
console.log(treeData[0].children?.[1].toggle) // true

见打字稿游乐场

我还可能会将索引路径预解析为一个整数数组,这样您就不必在每个循环中执行字符串操作。

也许就像:

代码语言:javascript
复制
function parseIndexPath(indexPath: string): number[] {
  return indexPath.split('/').map(n => parseInt(n))
}

见游乐场

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73807693

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档