根据多个键的重复值从对象数组中删除元素

时间:2016-06-27 05:02:30

标签: javascript filter

我有一个像这样的对象数组 -

var arr = [
    { type_id: "3", full_empty:"true", quantity:1},
    { type_id: "3", full_empty:"true", quantity:1},
    { type_id: "9", full_empty:"true", quantity:4},
    { type_id: "9", full_empty:"false", quantity:4},
    { type_id: "9", full_empty:"true", quantity:4},
    { type_id: "9", full_empty:"true", quantity:4},
    { type_id: "9", full_empty:"true", quantity:4}
];

我想删除具有相同 type_id full_empty 值的重复项。结果应如下所示 -

var arr = [
    { type_id: "3", full_empty:"true", quantity:1},
    { type_id: "9", full_empty:"true", quantity:4},
    { type_id: "9", full_empty:"false", quantity:4},
];

我已经搜索并找到了一些解决方案,但其中一些解决方案是删除重复的密钥或根据只有一个密钥的重复值删除重复项。一些需要的外部库。还有一些我无法理解的解决方案。有没有简单的方法在纯JavaScript中执行此操作?

编辑以便更好地理解 - 我已阅读此question。对该问题的接受答案是仅查找一个密钥的重复。在我的情况下,我必须找到多个键的重复。

9 个答案:

答案 0 :(得分:7)

您可以使用 Array.some() Array.reduce() 来使用纯函数将输入数组缩减为不同元素的数组,如下所示



    var arr = [
        { type_id: "3", full_empty:"true", quantity:1},
        { type_id: "3", full_empty:"true", quantity:1},
        { type_id: "9", full_empty:"true", quantity:4},
        { type_id: "9", full_empty:"false", quantity:4},
        { type_id: "9", full_empty:"true", quantity:4},
        { type_id: "9", full_empty:"true", quantity:4},
        { type_id: "9", full_empty:"true", quantity:4}
    ];

    var a = arr.reduce(function (accumulator, current) {
      if (checkIfAlreadyExist(current)) {
        return accumulator
      } else {
        return accumulator.concat([current]);
      }
      
      function checkIfAlreadyExist(currentVal) {
        return accumulator.some(function(item){
          return (item.type_id === currentVal.type_id &&
                  item.full_empty === currentVal.full_empty);
        });
      }
    }, []);
        
    console.log(a);




简明的ES6语法

可以使用 ES6 箭头函数和展开运算符编写更简洁的reduce,如下所示:



var arr = [
            { type_id: "3", full_empty:"true", quantity:1},
            { type_id: "3", full_empty:"true", quantity:1},
            { type_id: "9", full_empty:"true", quantity:4},
            { type_id: "9", full_empty:"false", quantity:4},
            { type_id: "9", full_empty:"true", quantity:4},
            { type_id: "9", full_empty:"true", quantity:4},
            { type_id: "9", full_empty:"true", quantity:4}
        ];

var a = arr.reduce((accumulator, current) => {
  if (checkIfAlreadyExist(current)) {
    return accumulator;
  } else {
    return [...accumulator, current];
  }

  function checkIfAlreadyExist(currentVal) {
    return accumulator.some((item) => {
      return (item.type_id === currentVal.type_id &&
              item.full_empty === currentVal.full_empty);
    });
  }
}, []);
            
console.log(a);




答案 1 :(得分:2)

尽管有其他解决方案,我建议使用以type_idfull_empty为密钥的哈希表,如果找到新的哈希表,则将hash设置为true。与Array#filter一起,您将获得一个包含唯一项目的新数组。



var arr = [{ type_id: "3", full_empty: "true", quantity: 1 }, { type_id: "3", full_empty: "true", quantity: 1 }, { type_id: "9", full_empty: "true", quantity: 4 }, { type_id: "9", full_empty: "false", quantity: 4 }, { type_id: "9", full_empty: "true", quantity: 4 }, { type_id: "9", full_empty: "true", quantity: 4 }, { type_id: "9", full_empty: "true", quantity: 4 }],
    filtered = arr.filter(function (a) {
        var key = a.type_id + '|' + a.full_empty;
        if (!this[key]) {
            this[key] = true;
            return true;
        }
    }, Object.create(null));

console.log(filtered);




ES6



var arr = [{ type_id: "3", full_empty: "true", quantity: 1 }, { type_id: "3", full_empty: "true", quantity: 1 }, { type_id: "9", full_empty: "true", quantity: 4 }, { type_id: "9", full_empty: "false", quantity: 4 }, { type_id: "9", full_empty: "true", quantity: 4 }, { type_id: "9", full_empty: "true", quantity: 4 }, { type_id: "9", full_empty: "true", quantity: 4 }],
    filtered = arr.filter(
        (temp => a =>
            (k => !temp[k] && (temp[k] = true))(a.type_id + '|' + a.full_empty)
        )(Object.create(null))
    );

console.log(filtered);




答案 2 :(得分:1)

//To search the element is already exisit or not.(to remove Duplicate)
    function searchExisting(type_id,full_empty,newArray){
        for(var i=0;i<newArray.length;i++){
            if(newArray[i].type_id==type_id && newArray[i].full_empty==full_empty){
                return true;
            }
        }
        return false;
    }

//loop through every element and push it into new array
    var arr2=[];
    for(var i=0;i<arr.length;i++){
        if(!searchExisting(arr[i].type_id,arr[i].full_empty,arr2)){
            arr2.push(arr[i]);
        }
    }
    console.log(arr2)

答案 3 :(得分:1)

您可以使用findforEach从此数组创建一个包含重复值的新数组

希望此代码段有用

var arr = ["Json Array object as supplied in the question"];

// A new array which will contain unique json object
var newArray = [];

//Loop through each of the object in the original array

arr.forEach(function(item) {
    // If newArray .length is zero then just push the first element
    // else in newArray find if a json object already exist which have same
    // type_id & full_empty. If it does not exist it will return undefined
    if (newArray.length !== 0) {
        var _isPresent = newArray.find(function(secItem) {
            return secItem.type_id === item.type_id && secItem.full_empty === item.full_empty
        })
        // If element is not present then push this json pbject
        if (_isPresent == undefined) {
            newArray.push(item)
        }
    } else {  // this will execute only once when newArray length is 0

        newArray.push(item)
    }
})
console.log(newArray)

JSFIDDLE

答案 4 :(得分:1)

这不像Nina answer那样令人敬畏,但可以被注意到并得到新答案。

&#13;
&#13;
var arr = [ { type_id: "3", full_empty: "true", quantity: 1 }, { type_id: "3", full_empty: "true", quantity: 1 }, { type_id: "9", full_empty: "true", quantity: 4 }, { type_id: "9", full_empty: "false", quantity: 4}, { type_id: "9", full_empty: "true", quantity: 4 }, { type_id: "9", full_empty: "true", quantity: 4 }, { type_id: "9", full_empty: "true", quantity: 4}];

var dict = {}, result = [];

arr.forEach((i, key) => {
  !dict[(key = i.type_id + i.full_empty)] 
      && (dict[key] = result.push(i));
})
console.log(result)
&#13;
&#13;
&#13;

答案 5 :(得分:0)

数组对象上有过滤器和地图。您可以使用过滤器来定位所需的非活动属性。它是一个布尔评估,返回&#34;过滤&#34;新阵列。

这是一个发布在Egghead.IO网站上的精彩视频教程,真正将其分解。

答案 6 :(得分:0)

如果您不想进入代码,那么您可以使用以下代码段: -

var sDat = [
{ sid:12, scode:"code", sname:"Deep" },
{ sid:12, scode:"code", sname:"Anand" },
{ sid:139, scode:"code", sname:"Singh"}
];

function cleanup(arr, prop) {
var new_arr = [];
var lookup  = {};

for (var i in arr) {
    lookup[arr[i][prop]] = arr[i];
}

for (i in lookup) {
    new_arr.push(lookup[i]);
}

return new_arr;
}

var n = cleanup(sDat, 'sid');
alert(n);

我希望这对你有用。

答案 7 :(得分:0)

这是我对Aditya Singh's answer的修改版本

var arr = [
                { type_id: "3", full_empty:"true", quantity:1},
                { type_id: "3", full_empty:"true", quantity:1},
                { type_id: "9", full_empty:"true", quantity:4},
                { type_id: "9", full_empty:"false", quantity:4},
                { type_id: "9", full_empty:"true", quantity:4},
                { type_id: "9", full_empty:"true", quantity:4},
                { type_id: "9", full_empty:"true", quantity:4}
            ];


    var a = arr.reduce((accumulator, current) => {

     const isAlreadyExist = accumulator.some(item => (
      item.type_id === currentVal.type_id && item.full_empty === currentVal.full_empty
     ))

     return isAlreadyExist(current) ? accumulator : [...accumulator, current];
    }, []);

    console.log(a);

答案 8 :(得分:0)

var arr = [
    { type_id: "3", full_empty:"true", quantity:1},
    { type_id: "3", full_empty:"true", quantity:1},
    { type_id: "9", full_empty:"true", quantity:4},
    { type_id: "9", full_empty:"false", quantity:4},
    { type_id: "9", full_empty:"true", quantity:4},
    { type_id: "9", full_empty:"true", quantity:4},
    { type_id: "9", full_empty:"true", quantity:4}
];

let op = [];

arr.forEach((el) => {
  if (isNotExist(el)){
    op.push(el)
  }
  function isNotExist(obj){
    return op.every(el => JSON.stringify(el) !== JSON.stringify(obj) )
  	
  }
})

console.log(op)