嵌套对象过滤数组-ES6

时间:2018-08-30 17:31:22

标签: javascript ecmascript-6

因此,下面是对象数组,我试图仅过滤具有type:y的对象。如您所见,对象数组还可以包含相同架构的嵌套数组,并且可以是N级嵌套。因此,请使用最优化的ES6功能帮助我实现这一目标。

[
    {
        name: 'a',
        type: 'x',
        array:
            [
                {   
                    name: 'l',
                    type: 'y',
                },
                {   
                    name: 'm',
                    type: 'y',
                },
                {   
                    name: 'n',
                    type: 'x',
                    array:
                        [
                            {   
                                name: 'x',
                                type: 'y',
                            },
                            {   
                                name: 'y',
                                type: 'y',
                            },
                            {   
                                name: 'z',
                                type: 'x',
                            }
                        ]
                }
            ]
    },
    {
        name: 'b',
        type: 'y',
    },
    {
        name: 'c',
        type: 'y',
    },

]

下面也是我为实现此目的而编写的代码。 希望改善性能并对其进行优化

filterFunction(fields) { 
    const result = [];
    (fields || []).forEach((field) => { 
      if (field.array) {
        const x = field;
        x.array = this.filterFunction(field.array);
        result.push(x);
      } else if (field.type !== 'x') {
        result.push(field);
      }
    });
    return result;
  }

2 个答案:

答案 0 :(得分:0)

您可以使用类似折叠的图案:

function walk(input, accumulator, state = []) {
  if (!(input instanceof Array)) input = [input];
  while (input.length > 0) {
    const item = input.shift();
    state = accumulator(item, state);
    const isObject = item !== null && typeof item == 'object';
    if (isObject && 'array' in item) {
      const children = item.array instanceof Array ? item.array : [item.array];
      Array.prototype.push.apply(input, children);
    }
  }
  return state;
}

如果您要过滤的树很大(很多子树),则可能会出现“超出最大调用堆栈大小”错误,并且您可能更喜欢这种迭代:

walk(array, (item, state) => {
  if (item && item.type == 'y')
    state.push(item)
  return state;
})

并按以下方式使用

{{1}}

答案 1 :(得分:0)

对于具有更深层过滤数组的新对象,您可以使用Object.assign对数组进行过滤。

function filter(array, type) {
    return array.reduce((r, o) => {
        var array = filter(o.array || [], type);
        if (o.type === type || array.length) {
            r.push(Object.assign({}, o, { array }));
        }
        return r;
    }, []);
}

var array = [{ name: 'a', type: 'x', array: [{ name: 'l', type: 'y', }, { name: 'm', type: 'y', }, { name: 'n', type: 'x', array: [{ name: 'x', type: 'y', }, { name: 'y', type: 'y', }, { name: 'z', type: 'x', }] }] }, { name: 'b', type: 'y', }, { name: 'c', type: 'y' }];

console.log(filter(array, 'y'));
.as-console-wrapper { max-height: 100% !important; top: 0; }