在 JavaScript 中过滤包含对象数组的数组

4
我有一个对象数组。每个对象在数组中也有一个数组。我想过滤这两个数组,即父级数组和嵌套数组。例如,我有一个如下的数组:
[{list:[1,2]},{list:[1,2,3]},{list:[1,2,3,4]}]

当我应用过滤器时,它会返回具有列表元素值大于2的对象,并且嵌套列表本身也被过滤。它应该返回:
[{list:[3]},{list:[3,4]}]

Obj1 没有返回,因为它内部的列表没有任何大于 2 的值,对于 Obj2 只返回列表:[3],对于 Obj3 只返回列表:[3,4]。
是否可以在不改变原始列表的情况下实现?
以下代码过滤具有大于 2 的元素的对象。
parent
  .filter(obj => obj.list.some(el => el > 2))

我该做什么? 如果我为嵌套数组应用过滤器,该怎么办?
...
  .filter(obj => obj.list.filter(el => el > 2))

然后我得到了[[3],[3,4]],但不是对象本身。也许有人知道解决办法?
2个回答

5

我会先筛选子列表,然后检查其长度:

var parent = [{list:[1,2]},{list:[1,2,3]},{list:[1,2,3,4]}];

parent = parent
  .filter(obj => {
    obj.list = obj.list.filter(el => el > 2);
    return obj.list.length > 0; // Technically just `return obj.list.length;` would work; I prefer the clarity of the comparison
  });
console.log(parent);

是的,以上内容可以更简洁地表达;我认为会影响清晰度,但这是一个判断问题:

var parent = [{list:[1,2]},{list:[1,2,3]},{list:[1,2,3,4]}];

parent = parent.filter(obj => (obj.list = obj.list.filter(el => el > 2)).length);
console.log(parent);


从技术上讲,我们不应该使用let代替var吗? - Thalaivar
@Thalaivar:从技术上讲?不,ES2015中两者都是完全有效的。:-)(尽管当我在思考ES2015时,我倾向于使用let而不是var;在上面的例子中,这将更多地涉及到风格问题而不是其他任何事情。) - T.J. Crowder

0
除了TJ Crowder的回答之外,我想提一下,您仍然会得到已变异的原始列表项。
最好将初始数组映射到具有过滤列表属性的新项中,然后过滤空列表。

const parent = [{list:[1,2]},{list:[1,2,3]},{list:[1,2,3,4]}];

const filtered = parent
    // filter nested lists first
    .map(obj => {
         // here we can use Object.assign to make shallow copy of obj, to preserve previous instance unchanged
         return Object.assign({}, obj, {
             list: obj.list.filter(el => el > 2)
         })
    })
    // then omit all items with empty list
    .filter(obj => obj.list.length > 0)
console.log(filtered);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接