Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何删除和计数对象数组中的重复项Javascript_Javascript_Arrays_Object_Ecmascript 6 - Fatal编程技术网

如何删除和计数对象数组中的重复项Javascript

如何删除和计数对象数组中的重复项Javascript,javascript,arrays,object,ecmascript-6,Javascript,Arrays,Object,Ecmascript 6,我在尝试转换一些数据时遇到了一个问题,我找到的所有可能的解决方案似乎都“丑陋”或不是最好的,所以问题就在这里 我有这样的数据: var myData = [ { action:{ remove_item: { text: "delete", textToDisplay: "Remove" } } }, { action:{ remove_item: { text: "dele

我在尝试转换一些数据时遇到了一个问题,我找到的所有可能的解决方案似乎都“丑陋”或不是最好的,所以问题就在这里

我有这样的数据:

var myData = [
  {
    action:{
      remove_item: { 
        text: "delete",
        textToDisplay: "Remove"
      }
    }
  },
  {
    action:{
      remove_item: {
        text: "delete",
        textToDisplay: "Remove"
      }
    }
  },
  {
    action:{
      add_item: {
        text: "add",
        textToDisplay: "Add"
      }
    }
  }
];
最后我需要得到这样的东西:

var myData = [
  {
    text: "delete",
    textToDisplay: "Remove"
    count: 2
  },
  {
    text: "add",
    textToDisplay: "Add"
    count: 1
  }
];
如果您注意到,我已经删除了重复项,添加了
操作
键和
计数
以及重复项的数量

我希望有人能使用ES6或以功能性的方式提供有趣的解决方案。

您可以使用和

这是一个非常简单的解决方案:

var myData=[
{操作:{文本:“删除”}},
{操作:{文本:“删除”}},
{操作:{文本:“添加”}}
];
常量组=(arr)=>{
减少常数=减少常数((acc,curr)=>{
const text=curr.action.text;
acc[文本]=acc[文本]| 0;
acc[文本]+;
返回acc;
}, {});
return Object.getOwnPropertyNames(reduced).map((prop)=>({text:prop,count:reduced[prop]}));
};
var分组=组(myData);

log(JSON.stringify(grouped,null,4))基于myData结构的要求。一种方法是使用Map来完成您想要做的事情,使用array.from记录对象的数量并将其放入数组

var myData=[{action:{remove_item:{text:“delete”,textToDisplay:{remove”}},{action:{remove_item:{text:“delete”,textToDisplay:{remove”}},{action:{add_item:{text:“add”,textToDisplay:“add”}};
//映射以跟踪元素
//键:操作的属性(例如添加项、删除项)
//值:obj{text,textToDisplay,count}
var map=newmap();
//遍历myData中的每个对象
myData.forEach(数据=>{
//遍历data.action中的每个属性
Object.keys(data.action).forEach(d=>{
让currKey=JSON.stringify(data.action[d]);
让currValue=map.get(currKey);
//如果键存在,则递增计数器
如果(当前值){
currValue.count+=1;
map.set(currKey,currValue);
}否则{
//否则,请在新对象中使用设置新关键点
设newObj={
text:data.action[d]。text,
textToDisplay:data.action[d]。textToDisplay,
计数:1,
}
地图集(currKey,newObj);
}
})
});
//从地图生成一个数组
var res=Array.from(map.map)(e=>e[1]);

控制台日志(res)从注释中,我假设此数据是可能的:

var myData = [
  {
    action:{
      remove_item: { 
        text: "delete",
        textToDisplay: "Remove"
      },
      edit_item: { 
        text: "edit",
        textToDisplay: "Edit"
      }
    }
  },
  {
    action:{
      remove_item: {
        text: "delete",
        textToDisplay: "Remove"
      },
      // note this _key_ is duplicated below (see note at the bottom)
      add_item: {
        text: "addy",
        textToDisplay: "Addy"
      }
    }
  },
  {
    action:{
      add_item: {
        text: "add",
        textToDisplay: "Add"
      }
    }
  }
];
可能的减速器如下所示:

myData.reduce(function(memo, obj, index) {
    let key,
        action = obj.action,
        entries = Object.entries(action),
        entry,
        data,
        keyIndex;

    // action may have multiple fields (see note)
    for (entry of entries) {
        // the object field name is the key (see note)
        // key = entry[0];

        // the text attribute is the key (see note)
        key = entry[1].text;

        // index where in result[] the object is 
        // already stored (if so)
        keyIndex = memo._keyIndex.indexOf(key);

        if (keyIndex == -1) {
            // key not indexed (and saved) yet
            data = {};
            Object.assign(data, entry[1], { count: 1 });
            memo.result.push(data);
            memo._keyIndex.push(key);
        } else {
            // key already indexed, get the data and 
            // increment counter
            data = memo.result[keyIndex];
            data.count++;
        }
    }

    if (index < myData.length - 1) {
        // for all items but last memo is an internal wrapper object
        return memo;
    } else {
        // for final item return the actual result
        return memo.result;
    }
}, { result: [] /* actual result, this is finally returned */, _keyIndex: [] /* temp. index of keys */ });
myData.reduce(函数(备忘录、对象、索引){
让钥匙,
动作,
条目=对象。条目(操作),
进入
数据,
关键词索引;
//操作可能有多个字段(请参见注释)
用于(条目的输入){
//对象字段名是键(请参见注释)
//键=条目[0];
//文本属性是键(请参见注释)
key=条目[1]。文本;
//索引对象在结果[]中的位置
//已存储(如果已存储)
keyIndex=memo.\u keyIndex.indexOf(键);
如果(键索引==-1){
//尚未索引(并保存)密钥
数据={};
赋值(数据,条目[1],{count:1});
memo.result.push(数据);
备注._keyIndex.push(按键);
}否则{
//键已索引,获取数据并
//增量计数器
数据=备忘录。结果[关键索引];
data.count++;
}
}
如果(索引
要理解此代码,您应该熟悉:

  • 逐项将数组转换为其他数据类型的步骤
  • 以数组形式获取对象的键值对的步骤
  • 迭代数组/对象项的步骤
这里有趣的是,“memo”对象在运行期间包含两个引用。这允许跟踪
\u keyIndex
中的重复键。仅使用最后一个元素,从
reduce()
返回
结果
数组

注:

  • for..of循环用于处理
    {action:{}}
    对象内的多个字段(来自对问题的评论)。如果不需要,使用for..of块中的代码处理
    条目[0]
  • 分配
    键的行确定检查重复的键。
    
    • 如果
      action
      中的字段名是确定键,那么第一行(注释)就足够了。(这会使“Addy”出现在结果中,计数两次。)
    • 如果动作对象中
      文本
      字段的值很重要,则需要第二行。(这会使“添加”和“添加”出现在结果中。)

根据确定键的不同,生成的对象可能仍有重复项,但此代码应能很好地指导您。

添加您尝试过但发现不太合适的解决方案会有所帮助。@d-reaper的可能重复这是一个具有不同数据结构的非常不同的问题,针对其他问题提出的解决方案不起作用this@D-收割者当然,有时动作可以有多个动作,这是因为数据以前已经处理过,我的意思是我正在从以前的结构中提取动作父属性动作可以有多个类型的动作吗?例如,
{action:{add_item:{…},remove_item:{…}}}
对不起,我对数据做了一个错误,我已经更新了我问题中的数据,用新数据你的答案不起作用,对不起,我同意你的看法,数据似乎有点多余,但我无法处理输出,所以我需要用