JavaScript/TypeScript:对对象数组中的重复对象进行计数,以便在 Item 上具有 amount 属性

JavaScript/TypeScript: count duplicate Objects in an Array of Objects to have an amount property on Item

提问人:Nikki 提问时间:6/6/2023 最后编辑:Nikki 更新时间:6/6/2023 访问量:57

问:

所以我有一系列项目。该数组中有重复的项目,我正在尝试计算这些重复项。这些重复项的计数应放入其中一个重复项中,而另一个项应丢弃。

我的意见:

(简体)

[
  {
    "id": "fishing_rod",
    "emoji": "🎣",
    "description": "Used to go fishing.",
    "category": "fishing",
  },
  {
    "id": "fishing_rod",
    "emoji": "🎣",
    "description": "Used to go fishing.",
    "category": "fishing",
  },
  {
    "id": "pickaxe",
    "emoji": "⛏️",
    "description": "Used to go mining.",
    "category": "mining",
  },
],

我在寻找什么:

[
  {
    "id": "fishing_rod",
    "emoji": "🎣",
    "description": "Used to go fishing.",
    "category": "fishing",
    "amount": 2
  },
  {
    "id": "pickaxe",
    "emoji": "⛏️",
    "description": "Used to go mining.",
    "category": "mining",
    "amount": 1
  },
]

到目前为止,我尝试过:

我尝试了一些东西,但无法到达那里。

我只走了这么远,我只能得到项目 ID 和计数。它看起来像这样:

const itemsArray = items.map((i) => i.id); // items being my input array (see top of this post)
const itemsUnique = [...new Set(itemsArray)];
const itemsCount = itemsUnique.map((item) => [item, itemsArray.filter((i) => i === item).length])

输出:

[
  [ "fishing_rod", 2 ],
  [ "pickaxe", 1 ],
]

但这并不是我真正想要的...... 一点帮助将不胜感激。<3

JavaScript 节点 .js 数组 TypeScript 对象

评论


答:

0赞 InSync 6/6/2023 #1

只需迭代并将它们分组为相同的:id

(可以在下面的片段中找到更简短的版本。

function mergeItems(items) {
  const grouped = items.reduce((record, item) => {
    if (Object.hasOwn(record, item.id)) {
      record[item.id].count++;
    } else {
      record[item.id] = { ...item, count: 1 };
    }
    return record;
  }, {});
  return Object.values(grouped);
}

尝试一下:

console.config({ maximize: true });

function mergeItems(items) {
  const grouped = items.reduce((record, item) => {
    record[item.id] ??= { ...item, count: 0 };
    record[item.id].count++;
    return record;
  }, {});
  return Object.values(grouped);
}

const input = [
  {
    "id": "fishing_rod",
    "emoji": "🎣",
    "description": "Used to go fishing.",
    "category": "fishing",
  },
  {
    "id": "fishing_rod",
    "emoji": "🎣",
    "description": "Used to go fishing.",
    "category": "fishing",
  },
  {
    "id": "pickaxe",
    "emoji": "⛏️",
    "description": "Used to go mining.",
    "category": "mining",
  },
];

console.log(mergeItems(input));
<script src="https://gh-canon.github.io/stack-snippet-console/console.min.js"></script>

0赞 code 6/6/2023 #2

我们可以用来删除重复项,同时增加计数。filter

const input = [{"id": "fishing_rod","emoji": "🎣","description": "Used to go fishing.","category": "fishing",},{"id": "fishing_rod","emoji": "🎣","description": "Used to go fishing.","category": "fishing",},{"id": "pickaxe","emoji": "⛏️","description": "Used to go mining.","category": "mining",}]

const output = input.filter((val, i, arr) => {
  const first = arr.findIndex(({ id }) => val.id === id)
  if(first === i)
    return val.amount = 1 // the current value is the first occurence
  else arr[first].amount++ // the current value is not the first occurence
})

console.log(output)

0赞 RAllen 6/6/2023 #3

从技术上讲,是单行:)

const source = [
  {
    "id": "fishing_rod",
    "emoji": "🎣",
    "description": "Used to go fishing.",
    "category": "fishing",
  },
  {
    "id": "fishing_rod",
    "emoji": "🎣",
    "description": "Used to go fishing.",
    "category": "fishing",
  },
  {
    "id": "pickaxe",
    "emoji": "⛏️",
    "description": "Used to go mining.",
    "category": "mining",
  },
];

const result = {};
source.forEach((item) => result[item.id] ? result[item.id].amount ++ : result[item.id] = { ...item, amount: 1});
console.log(Object.values(result));