【问题标题】:Remove similar objects from array从数组中删除相似的对象
【发布时间】:2016-08-22 22:25:24
【问题描述】:

我正在尝试从具有 4 个相同值和 1 个唯一值的数组中删除对象。

快速的 google 搜索提供了许多用于从数组中删除 相同 对象的选项,但不包括 相似 的对象。

数组示例:

var data = [
   {Date: "2016-04-27T09:03:45Z", Name: "Tito", Title: "Developer", Department:"IT", Company: "XXX"},
   {Date: "2016-04-27T08:07:45Z", Name: "Tito", Title: "Developer", Department:"IT", Company: "XXX"},
   {Date: "2016-04-27T10:23:45Z", Name: "Tito", Title: "Developer", Department:"IT", Company: "XXX"}
]

我曾尝试使用 lodash _uniq 函数,但它只需要一个属性即可匹配:

var non_duplidated_data = _.uniq(data, 'Name'); 

除日期外,所有值都相同。如何根据 4 个属性删除相同的对象?

【问题讨论】:

标签: javascript arrays object lodash


【解决方案1】:

您可以使用纯 Javascript 解决此问题。 只需检查每个对象的每个属性:

Array.prototype.allValuesSame = function() {
    for(var i = 1; i < this.length; i++) {
        if(this[i] !== this[0])
            return false;
    }
    return true;
}

var data = [
   {Date: "2016-04-27T09:03:45Z", Name: "Tito", Title: "Developer", Department:"IT", Company: "XXX"},
   {Date: "2016-04-27T08:07:45Z", Name: "Tito", Title: "Developer", Department:"IT", Company: "XXX"},
   {Date: "2016-04-27T10:23:45Z", Name: "Tito", Title: "Developer", Department:"IT", Company: "XXX"}
]

var tmpPropValues = {};
for (var property in data[0]) {
    tmpPropValues[property] = [];

    for(var i = 0; i < data.length; i++) {
        var obj = data[i];

    // store temporary in array
    if (obj.hasOwnProperty(property)) {
      var value = obj[property];

      tmpPropValues[property].push(value);
    }
  }

    if(tmpPropValues[property].allValuesSame()) {
      delete tmpPropValues[property];
  }
}

for(var prop in tmpPropValues) {
    var tmp = document.getElementById("result").innerHTML;
  document.getElementById("result").innerHTML = tmp+" "+prop;

}

我为你做了一个fiddle

【讨论】:

    【解决方案2】:

    使用 .uniqBy https://lodash.com/docs#uniqBy,它允许自定义标准来统一您的数组。

    【讨论】:

    • 我在理解语法时遇到了一些麻烦。我试过这个_.uniqBy($scope.data, "Job_Title", "Department");,它只根据第一个参数Job_Title计算。有什么建议吗?
    • @TietjeDK 使用这里给出的好方法:stackoverflow.com/questions/26306415/…
    【解决方案3】:

    您可以通过两个嵌套循环来执行此操作,这将针对自身迭代数组。

    var newArray = [];   //Result array
    
    //iterate
    data.forEach(function(item, index){
    
        var found = false; 
    
        //Go through the rest of elements and see if any matches  
        for (var i = index; i < data.length, i++) {
            if (item.name == data[i].name && item.title == data[i].title) // add more fields here
                found = true;      
        }   
    
        //Add to the result array if no duplicates found
        if (!found)
           newArray.push(item);
    })
    

    【讨论】:

      【解决方案4】:

      这可以帮助你,在这段代码中,我首先映射所有应该比较的属性,然后我减少数组以便只获得唯一的记录。

       var data = [
             {Date: "2016-04-27T09:03:45Z", Name: "Tito", Title: "Developer", Department:"IT", Company: "XXX"},
             {Date: "2016-04-27T08:07:45Z", Name: "Tito", Title: "Developer", Department:"IT", Company: "XXX"},
             {Date: "2016-04-27T10:23:45Z", Name: "Tito", Title: "Developer", Department:"IT", Company: "XXX"}
          ];
      
      var uniqueRecord = data.map(function(item){
          return {Name:item.Name,Title:item.Title,Department: item.Department,Company:item.Company};
      }).reduce(function(acc,curr){
          if(!Array.isArray(acc)){
              var copyOfAcc = JSON.parse(JSON.stringify(acc));
              acc = [];
              acc.push(copyOfAcc);
          }
          return (acc.indexOf(curr) > -1) ? acc.push(curr) : acc;
      
      });
      

      结果是:

      [ { Name: 'Tito',
          Title: 'Developer',
          Department: 'IT',
          Company: 'XXX' } ]
      

      然后您需要定义要保留的日期(第一个、最后一个、哪个?)并再次查找记录,为此简单的“forEach”应该可以工作。

      【讨论】:

        猜你喜欢
        • 2020-06-27
        • 2017-04-27
        • 2022-11-15
        • 2021-10-26
        • 1970-01-01
        • 2014-11-29
        • 1970-01-01
        • 2012-05-12
        • 2017-03-01
        相关资源
        最近更新 更多