簡體   English   中英

從對象數組獲取唯一元素數組

[英]Get array of unique elements from arrays of objects

我有如下數組:

files = [
       {name: 'Lorem', other: true},
       {name: 'Foo', other: true},
       {name: 'Bar', other: true}
      ];


files = [
       {name: 'Lorem', other: true},
       {name: 'Xxxxx', other: true}
      ];


files = [
       {name: 'Lorem', other: true},
       {name: 'Foo', other: true},
       {name: 'Epic', other: true},
       {name: 'Xxxxx', other: true}
      ];

我正在嘗試使用Underscore獲取具有唯一元素的合並數組,但是它不起作用。 這是我的代碼:

function getAllFiles(alldocs) {
  var all = [];

  _.each(alldocs, function(element) {
    all = _.union(all, element.files);
  });

  return all;
}

但是我得到一個重復項的數組。

使用下划線,您可以這樣做:

files1 = [
       {name: 'Lorem', other: true},
       {name: 'Foo', other: true},
       {name: 'Bar', other: true}
      ];


files2 = [
       {name: 'Lorem', other: true},
       {name: 'Xxxxx', other: true}
      ];


files3 = [
       {name: 'Lorem', other: true},
       {name: 'Foo', other: true},
       {name: 'Epic', other: true},
       {name: 'Xxxxx', other: true}
      ];
//append all  json
all = _.union(files1,files2, files3);
//get unique by define function which returns name (deciding factor for unique)
all = _.uniq(all, function(d){return d.name});
console.log(all);//prints the unique elements

這里的工作代碼

用簡單的Javascrift臨時對象和Array#forEach()解決方案

 var files1 = [{ name: 'Lorem', other: true }, { name: 'Foo', other: true }, { name: 'Bar', other: true }], files2 = [{ name: 'Lorem', other: true }, { name: 'Xxxxx', other: true }], result = function (array) { var o = {}, r = []; array.forEach(function (a) { if (!(a.name in o)) { o[a.name] = a; r.push(o[a.name]); } }); return r; }(files1.concat(files2)); document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>'); 

union調用之后,您需要應用uniq方法。

問題是uniq默認情況下使用===運算符來測試數組元素的相等性。 因此,如果您有對象數組,則將通過引用而不是值來比較每個對象,這顯然是不希望有的行為。 通過為uniq提供額外的參數-回調函數( iteratee )可以解決此問題,該函數會將數組元素轉換為簡單的可比較值。 您可以使用JSON.stringify方法,該方法返回對象的字符串表示形式。

function getAllFiles(alldocs) {
    var union = _.union.apply(null, alldocs.map(function(v) {
        return v.files;
    }));
    return _.uniq(union, function(v) {
        return JSON.stringify(v);
    });
}
var alldocs = [
    {files: [
       {name: 'Lorem', other: true},
       {name: 'Foo', other: true},
       {name: 'Bar', other: true}
    ]},
    {files: [
       {name: 'Lorem', other: true},
       {name: 'Xxxxx', other: true}
    ]},
    {files: [
       {name: 'Lorem', other: true},
       {name: 'Foo', other: true},
       {name: 'Epic', other: true},
       {name: 'Xxxxx', other: true}
    ]}
];
var result = getAllFiles(alldocs);

小提琴

使用lodash,可以使用_.uniqBy

result = _.uniqBy(result, function (e) {
  return e.name;
});

https://jsfiddle.net/mw230kea/1/

這是因為您使用的是對象數組,而下划線在比較項目 (例如名稱,其他) 時不知道要使用哪個對象屬性 ,這是一個干凈的解決方案:

   files =  _.chain(files).indexBy("name").values();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM