2016-03-04 64 views
1
數組

我有如同下列的數組:獲取獨特元素的數組從對象

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} 
     ]; 

我試圖獲得有關下劃線的獨特元素的合併數組,但它不工作。這是我的代碼:

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

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

    return all; 
} 

但我得到一個重複的項目數組。

+2

看到https://github.com/jashkenas/underscore/issues/2311 –

+1

你很可能http://underscorejs.org/#uniq也與'union' –

+0

的解決方案下面給出的只是'name'屬性的檢查,但可能你想要區分'name'和'other'屬性。循環訪問數組並檢查兩者。如果它只是你想檢查的單個值,你可以用地圖來做,並減少一行。 – MartijnK

回答

2

使用下劃線,你可以做這樣的:

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 

工作代碼here

1

在平原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>');

0

這是因爲你正在使用對象的數組和下劃線不知道哪個對象屬性比較項目(例如名稱,其他)時使用, 這裏是一個乾淨的解決方案:

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

你需要後union CA申請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); 

Fiddle

相關問題