2012-11-10 30 views
5

Interwebz'i birkaç saat aradıktan sonra aradığım çözümü bulamadım.JavaScript'teki Nesneler Dizisi Birliği?

İçinde çok fazla bilgi bulunan oyun nesneleri içeren iki dizim var. (ör. başlık, sümük, küçük resim, özet, tür, yayınlanma tarihi ...).

Dizisi 1. kayıt sırasında belirtilen kullanıcının ilgi alanlarıyla eşleşen nesneleri topluluğudur.

Dizisi 2. benzer kullanıcıların oyun satın eşleşen nesneleri topluluğudur. Mümkün, ve benim durumumda neler olduğu, iki özdeş oyunları oynayın - Array 1'de oyunu ilkinde Array 2. de geçerli:

Sorun (Benzer kullanıcılar ortak ilgi alanlarını paylaşan olanlardır) dizi oyun, kullanıcının çıkarlarıyla eşleştiği için orada. İkinci dizide oyun var çünkü benzer bir kullanıcı bu oyunu satın aldı.

Soru: Underscore.js size İki dizinin bir birlik veren güzel küçük bir fonksiyon birliği() http://underscorejs.org/#union sahiptir, ancak yalnızca ilkel değerler üzerinde nesnelerin dizisi ile çalışmaz. Bunu nasıl işleyebilirim, bana bir dizi nesne birliği verir mi?

+0

Peki gerek derin birleştirme ve genişletmek mi? https://gist.github.com/1868955 http://stackoverflow.com/questions/7549574/merge-js-objects-without-overwriting http://stackoverflow.com/questions/896043/how-can-i- birleştirme-2-javascript-nesneleri-population-in-one-if-they-d- – jcolebrand

+0

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

+1

Bu sizin sorunuz değil, biliyorum benzersiz gameIds kullanarak düşünüldü ve koleksiyonlarınız için anahtar: value nesnesi kullanıldı mı? – cbayram

cevap

14

Kendi başınıza kolayca kullanabilirsiniz. Bu durumda, fonksiyonu genel yaparız, böylece herhangi bir veri tipi (dizilerinin) dizisini alabilir ve sağlanan karşılaştırıcı işlevini kullanarak birleştirebiliriz.

// 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); 

Çeşitli nesne karşılaştırma uygulamaları için bkz. Object comparison in JavaScript. Liste boş olabilir

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

, bunun için ayrı boş bir nesne eklemek için emin olun: Yapabileceğiniz, genişletmek alt çizgi kullanma

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

Beni dövdü. Güzel uygulama. – L0j1k

+0

Hmm hayır işe yarıyor. Tanımlanmamış olarak döndürür. https://gist.github.com/4049901 –

+0

Evet, bir değeri geri çevirmeyi unuttuğumda bu şaşırtıcı değil. :) Düzenleme. –

1

jQuery yöntemini extend sahiptir.

+0

Yani underscore.js, ama sendika operasyonunu arıyordum. Anladığım kadarıyla iki nesneyi birleştirmek. Bir nesneyi dizide zaten varsa tamamen ortadan kaldırmak istiyorum. Sanırım uzatmayı kullanabilirsin(), sadece aklıma gelen ilk şey değildi. –

2

:

4

Sen çizgi yolu kullanarak bunu yapabilirsiniz:

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

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

It orijinal fonksiyonu _.union(*arrays) sadece bir iyileştirme, koleksiyon (nesnenin dizisi) çalışmak için bir iteratee ekledi.

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

sadece dizideki ile çalışıyor orijinal işlevi, benziyor: nasıl kullanılacağını İşte

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

Ve bonus tam örnek:

// 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

Koleksiyon birliğinde (son bonus tam bir örnek) kullanacağım: '_.uniqBy (_. Flatten (args, true), 'prop-id') https://lodash.com/docs/4.17.4 #uniqBy – Crisboot

1

Set (ES6/ES2015) size yardımcı olacaktır.

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)