如何在JavaScript中从对象数组中计算唯一值

6
我想计算唯一值的数量并将其放入新的数组中。 我有以下数组:
[
  { CategoryId: "b5c3f43f941c", CategoryName: "Category 1", CategoryColor: "cgreen" }
  { CategoryId: "9872cce5af92", CategoryName: "Category 2", CategoryColor: "purple" }
  { CategoryId: "b5c3f43f941c", CategoryName: "Category 1", CategoryColor: "cgreen" }
]

我希望得到以下结果的新数组:
[
    { CategoryId: "b5c3f43f941c", count: 2, CategoryColor: "cgreen" }
    { CategoryId: "9872cce5af92", count: 1, CategoryColor: "purple" }
]

在这个按id检查中,如果id相同则显示计数和新数据在新数组中。
希望你理解我的意思。
谢谢。

对于任何lodash用户:(_.uniqBy(arrayOfObjects,'propertyName')).length - Dean
4个回答

10
你可以使用 "for..of" 循环遍历数组,并创建一个临时对象来保存每次循环中的数据。如果在 tempObject 中存在相同的 id,则将计数器增加 1。

var arr = [
  { CategoryId: "b5c3f43f941c", CategoryName: "Category 1", CategoryColor: "cgreen" }
  , { CategoryId: "9872cce5af92", CategoryName: "Category 2", CategoryColor: "purple" }
  , { CategoryId: "b5c3f43f941c", CategoryName: "Category 1", CategoryColor: "cgreen" }
]

var tempResult = {}

for(let { CategoryColor, CategoryId } of arr)
  tempResult[CategoryId] = { 
      CategoryId, 
      CategoryColor, 
      count: tempResult[CategoryId] ? tempResult[CategoryId].count + 1 : 1
  }      

let result = Object.values(tempResult)

console.log(result)


4

使用reduce函数,并在回调函数内检查是否存在一个对象,其CategoryId与之匹配。如果匹配,则更新计数;否则创建一个新对象,并将其值添加到数组中。

let k = [{
    CategoryId: "b5c3f43f941c",
    CategoryName: "Category 1",
    CategoryColor: "cgreen"
  },
  {
    CategoryId: "9872cce5af92",
    CategoryName: "Category 2",
    CategoryColor: "purple"
  },
  {
    CategoryId: "b5c3f43f941c",
    CategoryName: "Category 1",
    CategoryColor: "cgreen"
  }
]

let result = k.reduce(function(acc, curr) {
  // Check if there exist an object in empty array whose CategoryId matches
  let isElemExist = acc.findIndex(function(item) {
    return item.CategoryId === curr.CategoryId;
  })
  if (isElemExist === -1) {
    let obj = {};
    obj.CategoryId = curr.CategoryId;
    obj.count = 1;
    obj.CategoryColor = curr.CategoryColor;
    acc.push(obj)
  } else {
    acc[isElemExist].count += 1
  }
  return acc;

}, [])

console.log(result)


1
您可以先对数组进行排序,然后再计算重复项。缺点是它会修改原始的yourArray,因为它被排序了,所以请小心使用。
yourArray.sort((a, b) => {
  if (a.CategoryName > b.CategoryName) {
    return 1;
  }
  if (a.CategoryName < b.CategoryName) {
    return -1;
  }
  return 0;
});

var pivot = yourArray[0];
pivot.count = 0;
var counted = [pivot];
yourArray.forEach(item => {
  if (item.CategoryId === pivot.CategoryId) {
    pivot.count++;
  } else {
    pivot = item;
    pivot.count = 1;
    counted.push(pivot);
  }
});

缺点是它会修改原始的yourArray,因为它被排序了,所以要小心使用。我最近读到了这个:https://2ality.com/2022/04/change-array-by-copy.html -- 我认为它是toSorted() - 值得研究一下。 - edwardsmarkf

0
const array_unique = require('array-hyper-unique').array_unique

let arr = [
  { CategoryId: "b5c3f43f941c", CategoryName: "Category 1", CategoryColor: "cgreen" }
  { CategoryId: "9872cce5af92", CategoryName: "Category 2", CategoryColor: "purple" }
  { CategoryId: "b5c3f43f941c", CategoryName: "Category 1", CategoryColor: "cgreen" }
]

array_unique(arr).length

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