从JavaScript对象获取唯一值并将其放入数组

时间:2020-05-04 17:17:33

标签: javascript reactjs

我有一个按照props.moves建立的JS对象:

0: {userId: 168, moveId: 198, moveName: "FirstSettlementMove", building: {…}}
1: {userId: 168, moveId: 200, moveName: "FirstSettlementMove", building: {…}}
2: {userId: 168, moveId: 202, moveName: "FirstSettlementMove", building: {…}}
3: {userId: 168, moveId: 204, moveName: "FirstSettlementMove", building: {…}}
4: {userId: 168, moveId: 206, moveName: "FirstSettlementMove", building: {…}}

我想编写一个遍历此对象所有元素的特定函数,因此从0开始到最后一个。然后,它应该检查moveName中的值,并将所有唯一的值放入数组中并返回该数组。所以基本上像这样:

function moveCollector(props.moves) {
        let arr = [];
           for (key=="moveName" in props.moves)
              add every unique value to arr
    }

有人为此提供方法或解决方案吗?对于具有唯一值的部分以及一个对象元素具有各种键的事实,我一无所知。

谢谢!

4 个答案:

答案 0 :(得分:1)

let moves = [
{userId: 168, moveId: 198, moveName: "FirstSettlementMove"},
{userId: 168, moveId: 200, moveName: "FirstSettlementMove"},
{userId: 168, moveId: 202, moveName: "FirstSettlementMove"},
{userId: 168, moveId: 204, moveName: "FirstSettlementMove"},
{userId: 168, moveId: 206, moveName: "FirstSettlementMove"}
]

function moveCollector(moves) {
     let unique=[]
     moves.forEach((move)=>{
       if(!unique.includes(move.moveName )){
             unique.push(move.moveName );
        }
     })
    return unique;
}

console.log("unique names of moves:",moveCollector(moves))

您可以这样做

 function moveCollector(moves) {
     let unique=[]
     moves.forEach((move)=>{
       if(!unique.includes(move.moveName )){
             unique.push(move.moveName );
        }
     })
    return unique;
}

答案 1 :(得分:1)

您可以使用reduce()创建一个名称为键的对象并读取键:

let names = Object.keys(list.reduce((acc, v) => {
  acc[v.moveName] = 1;
  return acc;
}, {}))

list = [{userId: 168, moveId: 198, moveName: "FirstSettlementMove"},
{userId: 168, moveId: 200, moveName: "FirstSettlementMove"},
{userId: 168, moveId: 202, moveName: "FirstSettlementMove"},
{userId: 168, moveId: 204, moveName: "FirstSettlementMove"},
{userId: 168, moveId: 206, moveName: "FirstSettlementMove"}]

let names = Object.keys(list.reduce((acc, v) => {
  acc[v.moveName] = 1;
  return acc;
}, {}))

console.log(names);

或者您可以使用Set:

let names = Array.from(list.reduce((acc, v) => acc.add(v.moveName), new Set()))

    list = [{userId: 168, moveId: 198, moveName: "FirstSettlementMove"},
    {userId: 168, moveId: 200, moveName: "FirstSettlementMove"},
    {userId: 168, moveId: 202, moveName: "FirstSettlementMove"},
    {userId: 168, moveId: 204, moveName: "FirstSettlementMove"},
    {userId: 168, moveId: 206, moveName: "FirstSettlementMove"}]

    let names = Array.from(list.reduce((acc, v) => acc.add(v.moveName), new Set()))

    console.log(names);

答案 2 :(得分:1)

从一个稍微简单的问题开始,然后逐步解决可能会更容易。假设我们要编写一个函数unique,该函数接受一个数字数组,并生成另一个数字数组,其中包含输入数组中每个唯一值之一。那是:

// *wishful thinking*

unique([1, 3, 1, 1, 2, 3, 4, 3, 4])
// => [1, 3, 2, 4]

一种方法是遍历输入数组,维护到目前为止我们看到的数字数组。对于每个数字,如果尚未看到,则将其添加到数组中。否则,我们继续。这就是可能的样子;

function unique(nums) {
  const seen = [];
  for (let num of nums) {
    if (!seen.includes(num)) {
      seen.push(num);
    }
  }
  return seen;
}

现在,要回答您的问题,我们将需要以一种关键的方式修改此功能:为了测试是否应将一个对象添加到seen数组中,我们需要查看是否有另一个具有相同对象的对象已经看到moveName的值。我们可以使用find方法来完成此操作:

function unique(objs) {
  const seen = [];
  for (let obj of objs) {
    if (!seen.find(({ moveName }) => moveName === obj.moveName)) {
      seen.push(obj);
    }
  }
  return seen;
}

不提这也可以通过reduce方法来实现,这让我很失落:

function unique(objs) {
  return objs.reduce((acc, obj) => (
    acc.find(({ moveName }) => obj.moveName === moveName)
    ? acc
    : [...acc, obj]
  ), []);
}

有人喜欢这个;别人讨厌它。

答案 3 :(得分:0)

喜欢一行代码的人的另一种方式:)

const moveCollector = (props.moves) =>
     props.moves.reduce(
       (acc, move) =>
         !acc.includes(move.moveName)
          ? [...acc, move.moveName]
          : acc,
       []
     );