Javascript:如何根据即将到来的索引值递归地分组数组

Javascript: How to recursively group arrays based upon upcoming index value

本文关键字:递归 数组 索引值 何根 即将到来 Javascript      更新时间:2023-09-26

我有一种情况,我想根据即将到来的索引的值将数组分组成块。让我们考虑这个例子

输入

var tokens = [{
    tag: null,
    line: 'starting of the file'
},
{
    tag: 'each',
    line: null
}, {
    tag: null,
    line: 'foo bar'
}, {
    tag: null,
    line: 'baz'
}, {
    tag: 'endeach',
    line: null
}, {
    tag: null,
    line: 'hello world'
}]

预期输出

[{
    tag: null,
    line: 'starting of the file'
},
{
    tag: 'each',
    line: null,
    childs: [{
        tag: null,
        line: 'foo bar'
    }, {
        tag: null,
        line: 'baz'
    }]
}, {
    tag: null,
    line: 'hello world'
}]

真正发生的是,在开始的each标记之后的所有元素都嵌套为子元素。现在这也可以递归地发生,在endeach之前可以有多个each标签。

希望这是有意义的!

使用Array.prototype.reduce(),每当遇到each时,我们将子数组添加到container数组中。每当遇到endeach时,就从container中删除最后一个数组。在container中,我们总是将项压入最后一个数组。最后,container中的第一个数组将包括树:

function fold(arr) {
  return arr.reduce(function(container, item) {
    if (item.tag === 'endeach') {
      container.pop();
      return container;
    }
    
    container[container.length - 1].push(item);
    if (item.tag === 'each') {
      item.children = [];
      container.push(item.children);
    }
    
    return container;
  }, [[]])[0];
}
var tokens = [{
    tag: null,
    line: 'starting of the file'
  }, {
    tag: 'each',
    line: null
  }, {
    tag: null,
    line: 'foo bar'
  }, {
    tag: 'each',
    line: null
  }, {
    tag: null,
    line: 'foo bar21'
  }, {
    tag: null,
    line: 'baz21'
  }, {
    tag: 'endeach',
    line: null
  }, {
    tag: 'each',
    line: null
  }, {
    tag: null,
    line: 'foo bar22'
  }, {
    tag: null,
    line: 'baz22'
  }, {
    tag: 'endeach',
    line: null
  },{
    tag: null,
    line: 'baz'
  }, {
    tag: 'endeach',
    line: null
  }, {
    tag: null,
    line: 'hello world'
  }
];
var result = fold(tokens);
console.log(result);