【问题标题】:Javascript - Create nested object from array based on edge conditionsJavascript - 根据边缘条件从数组创建嵌套对象
【发布时间】:2021-07-08 20:59:52
【问题描述】:

递归每次都害死我。

我有以下数组:

fooArray: Foo[] = 
[
  { foo: "a", indent: 0 },
  { foo: "b", indent: 1 },
  { foo: "c", indent: 2 },
  { foo: "d", indent: 1 },
  { foo: "e", indent: 2 },
  { foo: "f", indent: 2 },
  { foo: "g", indent: 1 },
  { foo: "h", indent: 0 },
]

我想将此映射到不同类型的对象 (TS),并根据对象的缩进值嵌套对象:

interface Bar {
  foo: string,
  bar?: Bar[]
}

barArray: Bar[] = 
[
  { 
    foo: "a", 
    bar: [
      { foo: "b",
        bar: [{ foo: "c" }],
      { foo: "d",
        bar: [
          { foo: "e" }, 
          { foo: "f"}
        ] 
      },
      {
        foo: "g"
      }
    ]
  },
  { foo: "h" }
]

我一直在尝试使用 reducer,但需要根据相邻数组成员来确定递归级别真的让我很头疼。如果有人有任何想法,将不胜感激!

【问题讨论】:

  • 我们可以使用数组方法非常接近。获得bar 属性是否总是缩进级别的“最后一个”项目(例如foo: a, bar…foo: c, bar…)。您的所有项目一次最多只能增加或减少一个缩进。它会跳过一个以上的缩进(1 ➞ 3 ➞ 5 等)吗?
  • 一次只能跳一个。如果不是,我将确保边缘条件只是缩进是否更大导致添加条。不,foos 列表中可能有多个条。我将尝试添加更多内容以澄清原始问题。我越来越接近使用递归reducer 和array.splice 的解决方案。当我接近时,我会发布我所拥有的。
  • 是的,请添加。我将把我半成品的答案留到以后再回来。

标签: javascript arrays reduce


【解决方案1】:

我在这里的解决方案完全是一项正在进行的工作,所以请不要测试或尝试它。我不得不离开一段时间,想把这个留在这里待会儿再来:

let fooArray = [
  { foo: "a", indent: 0 },
  { foo: "b", indent: 1 },
  { foo: "c", indent: 2 },
  { foo: "d", indent: 1 },
  { foo: "e", indent: 2 },
  { foo: "e1", indent: 1 },
  { foo: "e2", indent: 0 },
  { foo: "e3", indent: 1 },
  { foo: "f", indent: 2 },
  { foo: "g", indent: 1 },
  { foo: "h", indent: 0 },
];

// let barArray = fooArray.slice().flatMap((e,i,a) => i ? null : Array(a.filter(f => !f.indent).length).fill().map((f,j,b) => a.splice(0,Math.max(a.slice(1).findIndex(g => g.indent === 0)+1,1))));

// WIP // let barArray = fooArray.slice().flatMap((e,i,a) => i ? null : Array(a.filter(f => !f.indent).length).fill().map((f,j,b) => a.splice(0,Math.max(a.slice(1).findIndex(g => g.indent === 0)+1,1)))).map(e => e.map((f,i,a) => a[i+1]?.indent > f.indent ? { foo: f.foo, bar: a.splice(i+1,i+2) } : f).filter(f => f));

// WIP #2 // let barArray = fooArray.slice().map(e=>({...e})).flatMap((e,i,a) => i ? null : Array(a.filter(f => !f.indent).length).fill().map((f,j,b) => a.splice(0,Math.max(a.slice(1).findIndex(g => g.indent === 0)+1,1)))).map(e => e.reverse().map((f,i,a) => /*console.log(`a[i]: ${JSON.stringify(a[i])}\nf: ${JSON.stringify(f)}`) ||*/ a[i+1]?.indent < f.indent ? (a[i+1].bar = [{foo:f.foo}], a.splice(i,i+1)) : {foo:f.foo}).filter(f=>f).reverse());

// WIP #3 // let barArray = fooArray.slice().map(e=>({...e})).flatMap((_,i,a) => i ? null : Array(a.filter(e => !e.indent).length).fill().map(e => a.splice(0,Math.max(a.slice(1).findIndex(f => f.indent === 0)+1,1)))).map(e => e.length > 1 ? e.flatMap((_,i) => i ? null : Array(e.filter(e => !e.indent).length).fill().map(f => e.splice(0,Math.max(e.slice(1).findIndex(g => g.indent === 0)+1,1)))) : e);

// simple get object // let barArray = fooArray.slice().map(e=>({...e})).flatMap((_,i,a) => i ? null : Array(a.filter(e => !e.indent).length).fill().map(e => a.splice(0,Math.max(a.slice(1).findIndex(f => f.indent === 0)+1,1))));

// NEW WIP

fooArray.slice().map(e=>({...e})).flatMap((_,i,a) => i ? null : Array(a.filter(e => !e.indent).length).fill().map(e => a.splice(0,Math.max(a.slice(1).findIndex(f => f.indent === 0)+1,1)))).map(e => e.length > 1 ? { foo: e[0].foo, bar: e.slice(1) } : e[0])
.map(a => a.bar ? 
    ((a.bar = a.bar.reverse().flatMap((e,i) => 
        a.bar.findIndex((f,j) => j > i && e.indent !== f.indent) !== -1 ? 
            (a.bar.find((f,j) => j > i && e.indent !== f.indent).indent > e.indent ? e : (a.bar.find((f,j) => j > i && e.indent !== f.indent).bar = a.bar.splice(i,a.bar.findIndex((f,j) => j > i && e.indent !== f.indent))))
            : e
    ).reverse()), a)
    : a
)

console.log(barArray);

【讨论】:

  • 感谢您的帮助!我可能会尝试通过在这里使用您的一些想法来使我的想法更加扎实。我最终只写了一个 for 循环,它将循环缩进时间并将当前的“节点”设置为数组的最后一个栏。只要缩进只增加 1 就可以工作。
  • @jmroon 甜!你能把最终结果贴在这里让我测试吗?
  • 当然我会在明天发布。我需要对它进行 Foobarise 处理。 :p 这不是特别优雅,但确实有效。
猜你喜欢
  • 2019-06-13
  • 1970-01-01
  • 2018-10-17
  • 2019-04-23
  • 2019-10-06
  • 1970-01-01
  • 2021-11-28
  • 2019-09-23
  • 2022-01-10
相关资源
最近更新 更多