Javascript - 计算对象数组中的重复项并将计数存储为新对象 [英] Javascript - Counting duplicates in object array and storing the count as a new object

查看:19
本文介绍了Javascript - 计算对象数组中的重复项并将计数存储为新对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一组作为产品的 javascript 对象.这些产品以购物车的形式显示在列表中.

我想根据 _.id 值计算数组中重复产品的数量,并从数组中删除这些对象,并将它们与更新版本和名为 count 带有此对象出现的总次数的值.

到目前为止,我已经尝试了很多方法并且我已经在谷歌上进行了搜索,但是我发现没有任何方法可以正确地完成这项工作.

我将使用的数组类型示例如下:

<预><代码>[{_id:5971df93bfef201237985c4d",弹头:5971df93bfef201237985c4d",税收百分比:23,总成本:9.99,货币:欧元",},]

所以我希望我的最终结果是这样的 - 它删除了重复值并将其替换为相同的对象,但添加了一个名为 count 的新键,其值为对象最初的次数在数组中:

<预><代码>[{_id:5971df93bfef201237985c4d",弹头:5971df93bfef201237985c4d",税收百分比:23,总成本:9.99,货币:欧元",count: 2,//无论计数是多少},]

到目前为止,我正在使用这种方法:

变量计数 = [];

if (cart.cart.products != undefined) {让 namestUi = {渲染名称(名称){返回 Array.from(names.reduce((计数器,对象)=>counters.set(object._id, (counters.get(object._id) || 0) + 1),新地图()),([对象,计数]) =>{var filterObj = names.filter(function(e) {返回 e._id == 对象;});返回({filterObj,计数})});}};count = namestUi.renderNames(cart.cart.products);控制台日志(计数)}

但它返回这样的值:

{filterObj: Array//重复的数组,计数:2}{filterObj:数组,计数:1}

并且由于我将 React-Native 与列表视图一起使用,因此这样的事情将不起作用.

它只需要按照之前的方式(一个数组)存储项目,但有一个名为 count 的新子项.

欢迎任何帮助!

解决方案

我会坚持 reduce,使用 Map 并传播它的 values> 得到最终结果:

const names = [{ _id: 1 }, { _id: 1}, { _id: 2}, { _id: 1}];const 结果 = [...names.reduce( (mp, o) => {if (!mp.has(o._id)) mp.set(o._id, { ...o, count: 0 });mp.get(o._id).count++;返回 mp;}, new Map).values()];console.log(result);

或者,您可以先创建地图中所有计数为零的键(使用 Map 构造函数),然后再次迭代数据以更新计数器.这种任务拆分使代码比 reduce 更简洁:

const names = [{ _id: 1 }, { _id: 1}, { _id: 2}, { _id: 1}];const mp = new Map(names.map(o => [o._id, {...o, count: 0 }]));for (const {_id} of names) mp.get(_id).count++;const 结果 = Array.from(mp.values());console.log(result);

当您拥有多个键时,一种想法是使用 JSON.stringify([ ]) 加入这些键:

const names = [{cat: 1, sub: 1}, {cat: 1, sub: 2}, {cat: 2,子:1},{猫:1,子:1}];const 结果 = [...names.reduce( (mp, o) => {const key = JSON.stringify([o.cat, o.sub]);if (!mp.has(key)) mp.set(key, { ...o, count: 0 });mp.get(key).count++;返回 mp;}, new Map).values()];console.log(result);

I have an array of javascript objects that are products. These products are displayed in a list as a cart.

I want to count the number of duplicate products in the array based in the _.id value and remove these objects from the array and relace them with an updated version and a new key called count with a value of the total number of times this object comes up.

So far, I have tried numerous methods and I've searched all over google but there's nothing that I've found that can do the job correctly.

An example of the type of array that I will be using would be this:

[

    {  _id: "5971df93bfef201237985c4d", 
       slug: "5971df93bfef201237985c4d", 
       taxPercentage: 23, 
       totalCost: 9.99, 
       currency: "EUR", 
    },

]

so what I would want my end result to be would be something like this - it removes the duplicate value and replaces it with the same object but adds a new key called count with a value of the number of times the object initially was in the array:

[

    {  _id: "5971df93bfef201237985c4d", 
       slug: "5971df93bfef201237985c4d", 
       taxPercentage: 23, 
       totalCost: 9.99, 
       currency: "EUR", 
       count: 2, // whatever the count is
    },

]

So far I'm using this method:

var count = [];

if (cart.cart.products != undefined) {
    let namestUi = {
        renderNames(names){
            return Array.from(
                names.reduce( (counters, object) =>
                        counters.set(object._id, (counters.get(object._id) || 0) + 1),
                    new Map() ),
                ([object, count]) => {
                    var filterObj = names.filter(function(e) {
                        return e._id == object;
                    });

                    return ({filterObj, count})
                }
            );
        }
    };

    count = namestUi.renderNames(cart.cart.products);
    console.log(count)
}

but it returns the values like this:

{filterObj: Array // the array of the duplicates, count: 2}
{filterObj: Array, count: 1}

and since I am using React-Native with a list view something like this won't work.

It just needs to store the items the way it was before (an array) but with a new child called count.

Any help is welcomed!

解决方案

I would stick to reduce, use a Map and spread its values to get the final result:

const names = [{  _id: 1 }, { _id: 1}, { _id: 2}, { _id: 1}];

const result = [...names.reduce( (mp, o) => {
    if (!mp.has(o._id)) mp.set(o._id, { ...o, count: 0 });
    mp.get(o._id).count++;
    return mp;
}, new Map).values()];

console.log(result);

Or you can first create all the keys in the map with a zero count (using the Map constructor), and then iterate the data again to update the counter. This split of tasks makes the code more concise than with reduce:

const names = [{  _id: 1 }, { _id: 1}, { _id: 2}, { _id: 1}];

const mp = new Map(names.map(o => [o._id, {...o, count: 0 }]));
for (const {_id} of names) mp.get(_id).count++;
const result = Array.from(mp.values());

console.log(result);

When you would have more than one key, then one idea is to join those with JSON.stringify([ ]):

const names = [{cat: 1, sub: 1}, {cat: 1, sub: 2}, {cat: 2, sub: 1}, {cat: 1, sub: 1}];

const result = [...names.reduce( (mp, o) => {
    const key = JSON.stringify([o.cat, o.sub]);
    if (!mp.has(key)) mp.set(key, { ...o, count: 0 });
    mp.get(key).count++;
    return mp;
}, new Map).values()];

console.log(result);

这篇关于Javascript - 计算对象数组中的重复项并将计数存储为新对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆