使用基于嵌套值的数组过滤对象数组

IT技术 javascript filtering
2021-01-23 06:26:01

我正在尝试基于某个嵌套对象过滤数组。我准备了一些小提琴

输入数组如下所示:

let arrayOfElements = 
    [
        {
           "name": "a",
           "subElements": 
           [
             {"surname": 1},
             {"surname": 2}
           ]
        },
        {
           "name": "b",
           "subElements": 
           [
             {"surname": 3},
             {"surname": 1}
           ]
        },
        {
           "name": "c",
           "subElements": 
           [
             {"surname": 2},
             {"surname": 5}
           ]
        }
    ];

我希望这种情况下的输出如下所示:

let filteredArray = 
    [
        {
          "name": "a",
          "subElements": 
          [
            {"surname": 1}
          ]
        },
        {
          "name": "b",
          "subElements": 
          [
            {"surname": 1}
          ]
        }
];

我正在使用这个公式来做到这一点:

let filteredArray = arrayOfElements.filter((element) => element.subElements.some((subElement) => subElement.surname === 1));

输出几乎不错,但它返回包含所有带姓氏的对象的对象(最好检查小提琴:D),而不是将它们切掉。如何改进过滤?

6个回答

通过这种方式,您可以在任何级别的数组中尽可能深入并过滤元素,

arrayOfElements.map((element) => {
  return {...element, subElements: element.subElements.filter((subElement) => subElement.surname === 1)}
})

Spread operator将展开element然后过滤subElements将覆盖subElementsin 元素。

是的,这个答案更好。写入接受的答案时,对象扩展运算符不存在。
2021-03-24 06:26:01
@Aadam 你能分享你的数组吗?Array.map 不会修改原始数组,而是返回一个具有修改值的新数组。
2021-03-30 06:26:01
这应该是答案,因为接受的答案没有产生预期的输出
2021-04-10 06:26:01
这是修改原始数组
2021-04-12 06:26:01
这个解决方案的问题是将返回与原始元素相同数量的元素。它们的 subElements 数组将为空,因此更正方法是通过检查 subElements 的长度向结果映射添加过滤器。
2021-04-12 06:26:01

调用 后filter,您需要将结果通过管道传送到map,如下所示:

let filteredArray = arrayOfElements
  .filter((element) => 
    element.subElements.some((subElement) => subElement.surname === 1))
  .map(element => {
    let newElt = Object.assign({}, element); // copies element
    return newElt.subElements.filter(subElement => subElement.surname === '1');
  });

我在这里假设您不想操作原始数组。所以,我正在使用 Object.assign。

这个解决方案没有产生预期的输出:jsbin.com/dunuqeyeje/edit?js,console
2021-03-13 06:26:01
这不是只返回子元素数组而不是带有过滤子数组的完整对象吗?
2021-03-19 06:26:01
@LokeshSanapalli,在您的最后一次通话中,filter您需要更改surNamesurname. 然后它起作用了。那是我上面的错误。现在更正了。
2021-04-05 06:26:01
@WannyMiarelli 是正确的。它将返回过滤后的子数组,而不是带有过滤后姓氏的完整对象。上面的代码也有错误(字符串检查而不是整数和拼写错误 surName)。
2021-04-08 06:26:01
嗨@AndrewEisenberg!感谢您的输入。现在 4 年后,我决定将已接受的答案更改为使用扩展运算符的答案,因为它似乎更适合 2020 年:) 谢谢,没有任何不适,我希望:)
2021-04-10 06:26:01
let filteredArray = arrayOfElements
  .filter((element) => 
    element.subElements.some((subElement) => subElement.surname == 1))
  .map(element => {
    return Object.assign({}, element, {subElements : element.subElements.filter(subElement => subElement.surname == 1)});

  }); 
这返回了预期的响应
2021-03-23 06:26:01
当您将过滤后的数组与父对象“subElement”合并时,这将给出预期的响应。
2021-04-11 06:26:01

刚刚改进了上面的答案

let elements = 
    [
        {
           "name": "a",
           "subElements": 
           [
             {"surname": 1},
             {"surname": 2}
           ]
        },
        {
           "name": "b",
           "subElements": 
           [
             {"surname": 3},
             {"surname": 1}
           ]
        },
        {
           "name": "c",
           "subElements": 
           [
             {"surname": 2},
             {"surname": 5}
           ]
        }
    ];
var value = 1;

var filteredArray = elements
.filter(element => element.subElements
  .some(subElement => subElement.surname === value)
)
.map(element => {
  let n = Object.assign({}, element, {'subElements': element.subElements.filter(
    subElement => subElement.surname === value
  )})
  return n;
})

console.log(filteredArray)

试试这个解决方案:

data_filter = arrayOfElements.filter(function (element) {
    return element.subElements.some( function (subElement) {
        return subElement.surname === surname
    });
});
它不会返回确切的预期响应,而是返回找到的对象中的所有姓氏
2021-04-09 06:26:01