10

そのため、interwebz を数時間検索した後、探している解決策が見つかりませんでした。

内部に多くの情報を持つゲーム オブジェクトを含む 2 つの配列があります。(例: タイトル、スラッグ、サムネイル、概要、ジャンル、リリース日...)。

配列 1は、登録時に指定されたユーザーの関心に一致するオブジェクトのコレクションです。

Array 2は、同様のユーザーが購入したゲームに一致するオブジェクトのコレクションです。(類似ユーザーとは、共通の関心を共有するユーザーです)

問題: 可能性があります。私の場合、2 つの同一のゲームがあります。配列 1 のゲームは配列 2 にもあります。最初の配列には、ユーザーの興味に一致するため、ゲームが存在します。2 番目の配列では、同様のユーザーがそのゲームを購入したため、そのゲームが存在します。

質問: Underscore.js には、2 つの配列の和集合を与える素敵な小さな関数 union() http://underscorejs.org/#unionがありますが、オブジェクトの配列では機能せず、プリミティブ値でのみ機能します。どうすればオブジェクトの配列の結合を得ることができますか?

4

9 に答える 9

20

独自のものを非常に簡単に実装できます。この場合、関数をジェネリックにして、任意のデータ型の配列を取得し、提供された比較関数を使用して結合できるようにします。

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

さまざまなオブジェクト比較の実装については、JavaScript でのオブジェクト比較を参照してください。

于 2012-11-10T04:12:31.490 に答える
5

アンダースコアの方法を使用してそれを行うことができます:

// 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 を work コレクション (オブジェクトの配列) に追加して、元の functionを改良しただけです。

ここでそれを使用する方法:

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 } ]
于 2015-06-26T11:02:28.083 に答える
3

セット(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)

于 2016-12-30T16:21:32.567 に答える
1

アンダースコア拡張を使用すると、次のことができます。

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

リストが空になる可能性がある場合は、必ず空のオブジェクトを追加してください。

于 2013-09-17T01:04:47.070 に答える
1

jQueryにはメソッドがありますextend

$.extend(true, object1, object2);
于 2012-11-10T04:37:45.337 に答える
1

これがより良い解決策です

function arrayUnion() {
    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 = arrayUnion(a, b, c, function (item) {
    return item.id;
});

console.log(result); 
于 2018-09-11T05:26:52.503 に答える