如何删除对象数组中的重复项?

时间:2019-07-05 14:25:39

标签: javascript angular

我有一个看起来像这样的数组:

$x = $_GET['pageno']

我想删除重复的itemP,因此它的功能如下:

var array = 
[
    {
        key : { id : 1 , pack : "pack 1"},
        values : [
            {
                item : { id : 1 , name : "item1"},
                itemP : {id : 2 , name : "itemP12"}
            },
            {
                item : { id : 4 , name : "item4"},
                itemP : {id : 2 , name : "itemP12"}
            },
        ]
    }
]

当我尝试时,我总是会出错。可以这样做吗?

更新

我尝试这样做:

var array =
[
    {
        key : { id : 1 , pack : "pack 1"},
        values : [
            {
                item : { id : 1 , name : "item1"},
                itemP : {id : 2 , name : "itemP12"}
            },
            {
                item : { id : 4 , name : "item4"},
                itemP : null
            },
        ]
    }
]
  

JSON输入意外结束

我还尝试了一些过滤器,但是它不起作用:

  console.log(array.map(pack => 
    pack.values.map((item) => {
      var test =  JSON.stringify(item)
      var set = new Set(test)

      return Array.from(set).map((item)=> JSON.parse(item))
      }
    )

  ))

4 个答案:

答案 0 :(得分:1)

要获得预期结果,请使用以下使用地图选项

  1. 使用地图的循环数组
  2. 使用nameArr检查重复项并分配空值
  3. 循环值数组,并使用indexOf检查nameArr中的名称并分配null

var array = [
    {
        key : { id : 1 , pack : "pack 1"},
        values : [
            {
                item : { id : 1 , name : "item1"},
                itemP : {id : 2 , name : "itemP12"}
            },
            {
                item : { id : 4 , name : "item4"},
                itemP : {id : 2 , name : "itemP12"}
            }
        ]
    }
]


console.log(array.map(v => {
  let nameArr = []
  v.values = v.values.map(val => {
    if(nameArr.indexOf(val.itemP.name) !== -1){
      val.itemP.name = null
    }else{
      nameArr.push(val.itemP.name)      
    }
    return val
  })
  return v
}))

答案 1 :(得分:1)

您可以使用map和一个对象来检查其是否已经存在。像

var obj = {}

并遍历值

var values = [
            {
                item : { id : 1 , name : "item1"},
                itemP : {id : 2 , name : "itemP12"}
            },
            {
                item : { id : 4 , name : "item4"},
                itemP : {id : 2 , name : "itemP12"}
            }
        ]

values.map((v) => {
    if(!obj[v.itemP.id + '-' + v.itemP.name]) { 
     obj[v.itemP.id + '-' + v.itemP.name] = true; 
     return v;
    }
    return { item : v.item }

})

答案 2 :(得分:1)

我建议不要克隆每个关键属性,而是建议克隆整个结构,并在克隆的对象中将对象值设置为null,以避免无意间改变原始结构。

function nullifyDupes(array) {
  const clone = JSON.parse(JSON.stringify(array));
  const seen = {};

  clone.forEach(pack => {
    pack.values.forEach(items => {
      for (const item in items) {
        const id = items[item].id;

        if (seen[id]) items[item] = null;
        else seen[id] = true;
      }
    });
  });
  
  return clone;
}

const originalArray = [{
  key : { id : 1 , pack : "pack 1"},
  values : [{
    item : { id : 1 , name : "item1"},
    itemP : {id : 2 , name : "itemP12"}
  },
  {
    item : { id : 4 , name : "item4"},
    itemP : {id : 2 , name : "itemP12"}
  }]
}];

const mutatedArray = nullifyDupes(originalArray);
console.log(mutatedArray);

答案 3 :(得分:1)

您可以使用.map()将数组元素映射到不包含重复项的数组对象。对于.map()的每次迭代,您可以再次对内部值数组使用.map()将其转换为对象数组,以便将重复项转换为null。在这里,我保留了一个seen对象,该对象跟踪看到的属性及其字符串值。通过遍历对象中的所有属性(使用for...of),可以确定使用seen对象之前是否已看到键值对。

此方法的优点在于,它不仅适用于一个属性(即不仅适用于itemP),而且适用于任何其他重复的键值对。

请参见以下示例:

const array = [{key:{id:1,pack:"pack 1"},values:[{item:{id:1,name:"item1"},itemP:{id:2,name:"itemP12"}},{item:{id:4,name:"item4"},itemP:{id:2,name:"itemP12"}}]}];

const seen = {};
const res = array.map(obj => {
 obj.values = obj.values.map(vobj => {
   for (let p in vobj) {
     vobj[p] = seen[p] === JSON.stringify(vobj[p]) ? null : vobj[p];
     seen[p] = seen[p] || JSON.stringify(vobj[p]);
   }
   return vobj;
 });
 return obj;
});

console.log(res);

对于刚刚从数组中的所有对象中删除itemP的方法,您可以使用:

const array = [{key:{id:1,pack:"pack 1"},values:[{item:{id:1,name:"item1"},itemP:{id:2,name:"itemP12"}},{item:{id:4,name:"item4"},itemP:{id:2,name:"itemP12"}}]}];

let itemP = "";
const res = array.map(obj => {
  obj.values = obj.values.map(vobj => {
    vobj.itemP = itemP ? null : vobj.itemP;
    if('itemP' in vobj) {
      itemP = itemP || JSON.stringify(vobj.itemP);
    }
    
    return vobj;
  });
  return obj;
});

console.log(res);