【问题标题】:array of strings to tree data structure?字符串数组到树数据结构?
【发布时间】:2022-01-13 02:42:34
【问题描述】:

从服务器返回的数据包含一个字符串数组,其层次结构如下:

var array = [
 "house.bedroom.bed",
 "house.kitchen.spoon",
 "house.kitchen.knife",
 "house.bedroom.sofa",
 "house.bedroom.tv",
 "plants.trees",
 "house.birds.parrot.grey"
 ]

我已经成功地制作了一个树形数据结构作为对象,以便以下面的树形输出数据:

  house
    bedroom
      bed
      sofa
      tv
    kitchen
      spoon
      knife
    birds
      parrot
        grey
  plants
    trees

有没有办法选择一个字符串?例如,询问“厨房”我想像这样返回与该字符串相关的所有内容:

house.kitchen.knife
house.kitchen.spoon

这里是我学到的代码:

function find([key, values], string, temp = []) {
    var result;
    temp = temp.concat(key);
    if (key === string) {
        return temp.slice(1).join('.');
    }
    values.some(a => result = find(a, string, temp));
    return result;
}


var result = array.reduce((r, s) => {
        ('root.' + s).split('.').reduce((a, item) => {
            var array = a.find(([v]) => v === item);
            if (!array) {
                a.push(array = [item, []]);
            }
            return array[1];
        }, r);
        return r;
    }, []).pop();

console.log(find(result, 'kitchen'));
console.log(result);

我的输出是:

house.kitchen

【问题讨论】:

  • 我想你只需要过滤源数组array.filter((path) => path.split('.').includes('kitchen'))
  • 我试过它工作得很好,但目标是我需要将 array = [] 输出转换为对象以满足树数据结构,然后我应用 find() 函数来查找匹配的父级和子级相关的“厨房”........我制作了树,但无法运行 find() 来匹配“厨房”的父级和子级以满足预期输出
  • 你有一个从数组中生成树的函数。只需从过滤后的数组中制作树即可。

标签: javascript arrays data-structures tree hierarchy


【解决方案1】:

我建议过滤原始数组

const data = ["house.bedroom.bed","house.kitchen.spoon", "house.kitchen.knife","house.bedroom.sofa","house.bedroom.tv",
 "plants.trees","house.birds.parrot.grey"];
 
 
 const result = data.filter((path) => path.split('.').includes('kitchen'));
 
 console.log(result);
.as-console-wrapper{min-height: 100%!important; top: 0}

【讨论】:

  • 实际上这个解决方案很有帮助,但我需要进行更多研究才能从我的树数据结构而不是给定数据文件中打印出相同的输出结果
【解决方案2】:

我相信我明白你在问什么。我会用递归来解决这个问题。

function parse(items) {
   return items.reduce((acc, item) => {
      const k = item.slice(0, item.indexOf('.'))
      const v = item.slice(item.indexOf('.') + 1).split('.')
      
      const newItem = {
        [k]: v.length > 1 ? parse(v) : v
      }

      return Object.assign(acc, newItem)
   }, { })
}

这不是一个完整的解决方案,但应该可以理解总体思路。对于数组中的每个项目,将其拆分为一个键和一个值。键是第一个. 之前的字符串,值是. 之后的单个字符串,或者是包含子对象的对象。

【讨论】:

  • 嗨..谢谢你的帮助。我应该如何设置这个递归???
  • 您要问的几乎是回溯解决方案。数组中的元素没有相对顺序,这只会使事情复杂化。对阵列进行简单的扫描应该会更好。或者您可以修改您的树对象以包含叶级别的完整路径。
  • 我想这可以通过一些努力变得非常简单。你可能是对的,但这对我来说似乎是一个很好的递归机会,因为问题是分形的。为"house.bedroom.bed" 完成的工作必须为"bedroom.bed" 再次完成。
猜你喜欢
  • 1970-01-01
  • 2011-08-04
  • 1970-01-01
  • 2014-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多