2012-11-10 78 views
5

因此,在搜索interwebz幾個小時後,我還沒有找到我正在尋找的解決方案。JavaScript中對象數組的聯合?

我有兩個數組包含內部有很多信息的遊戲對象。 (例如標題,slu,,縮略圖,摘要,流派,發佈日期......)。

The Array 1是符合用戶在註冊期間指定的興趣的對象的集合。

陣列2是匹配購買類似用戶的遊戲對象的集合。 (類似的用戶是那些共同的利益)

問題:這是可能的,在我的情況發生了什麼,有兩個相同的遊戲 - 數組1中的遊戲也在數組2中。在第一個陣列遊戲在那裏,因爲它符合用戶的興趣。在第二個陣列中,遊戲就在那裏,因爲類似的用戶已經購買了該遊戲。

問題:Underscore.js有一個可愛的小功能結合()http://underscorejs.org/#union,給你兩個數組的聯合,但它不具有對象的數組,只能在原始值的工作。我怎麼能讓它工作給我一個對象數組的聯合?

+0

所以,你需要的是一個深刻的合併和擴展? https://gist.github.com/1868955 http://stackoverflow.com/questions/7549574/merge-js-objects-without-overwriting http://stackoverflow.com/questions/896043/how-cani-i-合併2-javascript-objects-populating-the-properties-in-one-if-they -d – jcolebrand

+0

http://phrogz.net/JS/ArraySetMath.js – Phrogz

+1

我知道這不是你的問題,但是你有沒有考慮使用獨特的gameIds並使用key:value對象來進行收藏? – cbayram

回答

14

你可以很容易地實現你自己。在這種情況下,我們使函數具有通用性,以便它可以使用任何數據類型的數組,並使用提供的比較函數將它們聯合起來。

// arr1 and arr2 are arrays of any length; equalityFunc is a function which 
// can compare two items and return true if they're equal and false otherwise 
function arrayUnion(arr1, arr2, equalityFunc) { 
    var union = arr1.concat(arr2); 

    for (var i = 0; i < union.length; i++) { 
     for (var j = i+1; j < union.length; j++) { 
      if (equalityFunc(union[i], union[j])) { 
       union.splice(j, 1); 
       j--; 
      } 
     } 
    } 

    return union; 
} 

function areGamesEqual(g1, g2) { 
    return g1.title === g2.title; 
} 

// Function call example 
arrayUnion(arr1, arr2, areGamesEqual); 

有關各種對象比較實現,請參閱Object comparison in JavaScript

+0

打敗我吧。很好的實施。 – L0j1k

+0

嗯沒有運氣得到它的工作。返回未定義。 https://gist.github.com/4049901 –

+0

是的,當我忘記「返回」一個值時,這並不令人驚訝。 :)編輯。 –

1

jQuery有方法extend

$.extend(true, object1, object2); 
+0

那麼underscore.js,但我正在尋找一個工會運作。從我所瞭解的用於合併兩個對象的方面擴展。如果它已經在數組中,我想完全消除一個對象。我想你可以使用extend(),這並不是我想到的第一件事。 –

2

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

var objects = [{ bar : 1, nuts : 2} , {foo : 3, nuts : 4}] 
_.extend.apply(this,objects) 

如果該列表可以是空的,一定要空對象追加到它。

4

您可以使用下劃線的方式做到這一點:

// collectionUnion(*arrays, iteratee) 
function collectionUnion() { 
    var args = Array.prototype.slice.call(arguments); 
    var it = args.pop(); 

    return _.uniq(_.flatten(args, true), it); 
} 

它只是原有功能_.union(*arrays)的改良效果,添加iteratee工作集合(對象的數組)。

這裏如何使用它:

var result = collectionUnion(a, b, c, function (item) { 
    return item.id; 
}); 

這是剛剛與陣列工作在原有的功能,看起來像這樣:

_.union = function() { 
    return _.uniq(flatten(arguments, true, true)); 
}; 

而且在獎金一個完整的例子:

// collectionUnion(*arrays, iteratee) 
function collectionUnion() { 
    var args = Array.prototype.slice.call(arguments); 
    var it = args.pop(); 

    return _.uniq(_.flatten(args, true), it); 
} 

var a = [{id: 0}, {id: 1}, {id: 2}]; 
var b = [{id: 2}, {id: 3}]; 
var c = [{id: 0}, {id: 1}, {id: 2}]; 

var result = collectionUnion(a, b, c, function (item) { 
    return item.id; 
}); 

console.log(result); // [ { id: 0 }, { id: 1 }, { id: 2 }, { id: 3 } ] 
+0

在收集聯合(最後一個獎金一個完整的例子),我將使用:'_.uniqBy(_。flatten(args,true),'prop-id')'https://lodash.com/docs/4.17.4 #uniqBy – Crisboot

1

Set(ES6/ES2015)會幫助你。

const info1 = {id: 1} 
 
const info2 = {id: 2} 
 
const info3 = {id: 3} 
 

 
const array1 = [info1, info2] 
 
const array2 = [info1, info3] 
 

 
const union = [...new Set([...array1, ...array2])] 
 

 
console.log(union)