根据对象的不同值过滤数组

时间:2020-10-21 15:50:33

标签: javascript node.js

我想简化对象过滤的数组。假设我有以下数组,

const users = [{
    name: "user1",
    gender: "m"
  }, {
    name: "user2",
    gender: "f"
  }, {
    name: "user3",
    gender: "f"
  }, {
    name: "user4",
    gender: "m"
  }, {
    name: "user5",
    gender: "m"
  }];

例如,我需要按男性或女性过滤所有用户,因此我要遍历过滤对象属性:

const fUsers = users.filter(user => user.gender === "f");
const mUsers = users.filter(user => user.gender === "m");

const results = [fUsers, mUsers];
console.log(results);

有没有一种更好的过滤方法可以一次完成,所以我可以将结果分成多个数组。

5 个答案:

答案 0 :(得分:4)

您可以使用reduce函数,并在累加器中传递一个嵌套数组。在回调中检查性别,您可以使用acc[0]在累加器的第一个嵌套数组或acc[1]

中添加元素

const users = [{
  name: "user1",
  gender: "m"
}, {
  name: "user2",
  gender: "f"
}, {
  name: "user3",
  gender: "f"
}, {
  name: "user4",
  gender: "m"
}, {
  name: "user5",
  gender: "m"
}];

const newArr = users.reduce((acc, curr) => {
  if (curr.gender === 'f') {
    acc[0].push(curr)
  } else {
    acc[1].push(curr)
  }
  return acc;
}, [
  [],
  []
]);

console.log(newArr)

或者,您也可以使用普通的for循环

const users = [{
  name: "user1",
  gender: "m"
}, {
  name: "user2",
  gender: "f"
}, {
  name: "user3",
  gender: "f"
}, {
  name: "user4",
  gender: "m"
}, {
  name: "user5",
  gender: "m"
}];

let arr = [
  [],
  []
];
for (let i = 0; i < users.length; i++) {
  users[i].gender === 'f' ? arr[0].push(users[i]) : arr[1].push(users[i])
};

console.log(arr)

答案 1 :(得分:3)

这可以使用Array.reduce完成。

Array.reduce回调中,如果性别为m,则可以从pushacc[0];如果genderf,则可以{ {1}}至push

acc[1]

答案 2 :(得分:2)

基本方法

forEach

基本上对于数组的任何类型的操作,都可以使用forEach。在这种情况下,您只需创建所需的帮助变量并在forEach中处理过滤器逻辑即可。

const males = []
const females = []
users.forEach(u=> u.gender === 'm' ? males.push(u) : females.push(u))

另一个javascript循环

另一个简单的解决方案是使用JavaScript loops中的一个,在我的示例中,我选择了for-in,但原理与forEach示例中的相同

const males = []
const females = []
for (u in users) {
    if (u.gender === 'm') {
        males.push(u)
    } else { 
        females.push(u)
    }
}

高级方法

减少

Reduce是允许处理数组循环并将结果存储到称为累加器的单个变量的功能,该变量在每个循环步骤中共享。我们可以使用[[],[]] =>数组累加器数组

const [males, females] = users.reduce((acc, user) => {
      if (user.gender === 'm') {
        acc[0].push(u)
      } else {
        acc[1].push(u)
      }
      return acc;
    }, [[], []])

减少单线

与最后一个原理相同,但重构为一行。 (不是野兽的可读性)

const [males, females] = users.reduce((acc, u) => (u.gender === 'm' ? acc[0].push(u) : acc[1].push(u), acc), [[],[]])

lodash /下划线

如果使用lodash,则可以使用groupBy函数,该函数使用包含过滤器属性和数组值的键创建对象,您也可以在underscore中找到该函数。

const result = _.groupBy(users, 'gender'));
// { 'm': [{male1, male2}], 'f': [female1, female2] }

答案 3 :(得分:0)

这将起作用,而不是两个过滤器,您可以简化为两个数组组成的数组,并按需进行排序。 acc是在减少使用的功能之后设置的。

const sortedByGender =users.reduce((acc, user)=>{
  user.gender==="f"?acc[0].push(user):acc[1].push(user);
  return acc;
},[[],[]]);

答案 4 :(得分:0)

您可以按性别分组并进行销毁,并重命名为所需的变量名。

const
    users = [{ name: "user1", gender: "m" }, { name: "user2", gender: "f" }, { name: "user3", gender: "f" }, { name: "user4", gender: "m" }, { name: "user5", gender: "m" }],
    { f: fUsers, m: mUsers } = users.reduce((r, o) => ((r[o.gender] ??= []).push(o), r), {});

console.log(fUsers);
console.log(mUsers);
.as-console-wrapper { max-height: 100% !important; top: 0; }