Javascript在保留最新版本的同时删除具有重复属性的数组对象

时间:2016-06-07 04:35:28

标签: javascript arrays duplicates underscore.js

我正在尝试删除具有重复ID但属性不同的同一对象的旧版本。

我的数组包含对象修改的历史记录,它看起来像这样:

[

  {
    id:"1",
    status:"foo",
    day: "01/01/1111"
  },
  {
    id:"2",
    status:"foo",
    day: "01/01/1111"
  },
  {
    id:"1",
    status:"bar",
    day: "02/01/1111"
  },

]

我想过滤此数组,因此没有重复ID的对象。但是保留了最新版本。在这种情况下,id为id。保留status:'bar'的版本。

我该怎么做呢?我在项目的其他部分使用underscore.js。我知道它有_.uniq。但我不知道如何使用它,以便它给我最新版本。

顺便说一下,我看到了this question,这与我的要求非常相似。但这是从5年前开始的,所以我想知道是否有更现代的方式来做htings。

4 个答案:

答案 0 :(得分:0)

这是你要追求的东西吗?

function updateList(a_list) {

    var seen = {};

    for (var entry in a_list) {
        var id = a_list[entry]["id"];

        if (seen.hasOwnProperty(id)) {
            var current_newest_date = new Date(seen[id]["day"]).getTime();
            var check_newest_date = new Date(a_list[entry]["day"]).getTime();

            if (current_newest_date < check_newest_date) {
                 seen[id] = a_list[entry];
            }

        } else {
            seen[id] = a_list[entry];
        }
    }

    var updated = [];
    for (var newest in seen) {
        updated.push(seen[newest]);
    } 
    return updated;
} 

这假定您的日期是月/日/年格式。

答案 1 :(得分:0)

你应该试试这个:

按日期降序排列数组

data.sort(function(a,b) {
    if ( new Date(a.day) > new Date(b.day) )
        return -1;
    if ( new Date(a.day)< new Date(b.day))
        return 1;
    return 0;
} );

在此之后,您可以删除重复的对象

var temp = {};
for(var i = 0; i < data.length ; i++ ){
    var obj = data[i];
    if(temp[obj.id] >= 0){
        data.splice(i, 1);
        i--;
    }
    temp[obj.id] = i;
}
console.log(data)

它也很简单.. :))

答案 2 :(得分:0)

按id对数组进行排序,并按日过滤生成的数组

function Filter(arrObjs){

  function sortId(a, b){
    return a.id - b.id;
  }

  var y = arrObjs.sort(sortId);

  var result = [];

  var max = y[0].day;
  for(var i = 1; i < y.length; i++){

    if(y[i -1].id == y[i].id){
        if(y[i].day > max){
           max = y[i].day;
        }
    }
    else{
        result.push(y[i -1]);
        max = y[i].day;
        if(i + 1 === y.length)
           result.push(y[i]);
    }
  }

  return result;
}

答案 3 :(得分:0)

没有任何过滤器和排序,具有O(n)(单程)的完全高性能解决方案。请注意,在某些情况下,它可能会导致稀疏数组,因为我们使用id作为索引。

&#13;
&#13;
var data = [{id:"1",status:"foo",day: "01/01/1111"},{id:"2",status:"foo",day: "01/01/1111"},{id:"1",status:"bar",day: "02/01/1111"},],
 reduced = data.reduce((p,c) => {var d1 = !!p[c.id] && new Date(p[c.id].day),
                                     d2 = new Date(c.day);
                                 (!d1 || d1 < d2) && (p[c.id] = c);  // if no d1 or d1 < d2 insert at index position designated by the id
                                 return p;},[]);
console.log(reduced);
var s = new Set(reduced); // now only one undefined left
s.delete(undefined); // get rid of that one too and use as a set or
reduced = [...s]; //get back your now properly reduced array.
console.log(reduced);
&#13;
&#13;
&#13;

如果是上面的稀疏数组,那么在没有id的索引处将有未定义的值。然后你可以通过像

那样简单地摆脱它们
var s = new Set(reduced); // now only one undefined left
s.delete(undefined); // get rid of that one too and use as a set or
reduced = [...s]; //get back your now properly reduced array.