57

Question と UserProfile の 2 つの配列があります。

  • : userProfiles[] 配列には{ id, name }オブジェクトが含まれます
  • : questions[] 配列には{ id, text, createdBy }オブジェクトが含まれています

質問のcreatedBy整数は、常に の id 値の 1 つですuserProfiles

データベースを使用している場合に2つのSQLテーブルを結合するのとほぼ同じ方法で配列を「結合」できる方法はありますか?

最終結果として必要なのは、次を含む配列です

{ id, text, name }

対応する SQL は次のとおりです。

SELECT u.id, q.text, u.name 
FROM userProfiles u 
JOIN questions q ON q.createdBy=u.id
4

15 に答える 15

7

私は常にunderscore.jsを使用しています。これは、この問題を解決できる配列と「マップリデュース」を適切にサポートしているためです。

ここにあなたの質問の解決策があります(元の投稿が示唆するように、ユーザーごとに1つの質問しかないと仮定しています)

http://jsfiddle.net/x5Z7f/

(ブラウザーコンソールを開いて出力を確認します)

    var userProfiles = [{ id:'1', name:'john' }, { id:'2', name:'mary' }];

var questions =[ { id:'1', text:'question john', createdBy:'1' }, { id:'2', text:'question mary', createdBy:'2' }];

var rows = _.map(userProfiles, function(user){ 
    var question = _.find(questions, function(q){ return q.createdBy == user.id });
    user.text = question? question.text:'';
    return user; 
})

_.each(rows, function(row){ console.log(row) });

上記の回答は、結合列として id == createdBy を使用していることを前提としています。

于 2013-07-06T07:01:49.607 に答える
7

私だったら、次のようにアプローチします。

セットアップ:

var userProfiles = [], questions = [];

userProfiles.push( {id:1, name:'test'} );
userProfiles.push( {id:2, name:'abc'} );
userProfiles.push( {id:3, name:'def'} );
userProfiles.push( {id:4, name:'ghi'} );

questions.push( {id:1, text:'monkey', createdBy:1} );
questions.push( {id:2, text:'Monkey', createdBy:1} );
questions.push( {id:3, text:'big',    createdBy:2} );
questions.push( {id:4, text:'string', createdBy:2} );
questions.push( {id:5, text:'monKey', createdBy:3} );

まず、リンク ID をキーとして使用するルックアップ オブジェクトを作成します。

var createObjectLookup = function( arr, key ){
  var i, l, obj, ret = {};
  for ( i=0, l=arr.length; i<l; i++ ) {
    obj = arr[i];
    ret[obj[key]] = obj;
  }
  return ret;
};

var up = createObjectLookup(userProfiles, 'id');

これで、簡単に質問を進めて、マージするユーザー オブジェクトを見つけることができます。

var i, l, question, user, result = [];
for ( i=0, l=questions.length; i<l; i++ ) {
  if ( (question = questions[i]) && (user = up[question.createdBy]) ) {
    result.push({
      id: question.id,
      text: question.text,
      name: user.name
    });
  }
}

これで、必要なものがすべて揃っているはずですresult

console.log(result);
于 2013-07-06T07:24:39.877 に答える
4

これは、何とか一般的な解決策を作ろうとする私の試みです。私が使用Array.mapしていて、Array.indexここにメソッドがあります:

var arr1 = [
    {id: 1, text:"hello", oid:2},
    {id: 2, text:"juhu", oid:3},
    {id: 3, text:"wohoo", oid:4},
    {id: 4, text:"yeehaw", oid:1}
];
var arr2 = [
    {id: 1, name:"yoda"},
    {id: 2, name:"herbert"},
    {id: 3, name:"john"},
    {id: 4, name:"walter"},
    {id: 5, name:"clint"}
];

function merge(arr1, arr2, prop1, prop2) {
    return arr1.map(function(item){
        var p = item[prop1];
        el = arr2.filter(function(item) {
            return item[prop2] === p;
        });
        if (el.length === 0) {
            return null;
        }
        var res = {};
        for (var i in item) {
            if (i !== prop1) {
                res[i] = item[i];
            }
        }
        for (var i in el[0]) {
            if (i !== prop2) {
                res[i] = el[0][i];
            }
        }
        return res;
    }).filter(function(el){
        return el !== null;
    });
}

var res = merge(arr1, arr2, "oid", "id");
console.log(res);

したがって、基本的には、prop1 が、prop2 が prop1 と等しい array2 内のアイテムのすべてのプロパティに置き換えられるように、2 つの配列と各配列に 1 つのプロパティを定義できます。

この場合の結果は次のようになります。

var res = [
    {id: 1, text:"hello", name:"herbert"},
    {id: 2, text:"juhu", name:"john"},
    {id: 3, text:"wohoo", name:"walter"},
    {id: 4, text:"yeehaw", name:"yoda"}
];

複数の一致がある場合、最初の項目が使用され、一致がない場合、オブジェクトは結果の配列から削除されることに注意してください。

フィドル

于 2013-07-06T08:31:19.140 に答える
2

reducemapを使用してこれを行うことができます。

まず、ID から名前へのマッピングを作成します。

var id2name = userProfiles.reduce(function(id2name, profile){
    id2name[profile.id] = profile.name;
    return id2name;
}, {});

次に、質問の新しい配列を作成しますが、ID の代わりに質問を作成したユーザーの名前を使用します。

var qs = questions.map(function(q){
    q.createdByName = id2name[q.createdBy];
    delete q.createdBy;
    return q;
});
于 2013-07-06T11:05:10.063 に答える
-2

最初に jQuery.merge() を使用し、次に jQuery.unique() を使用してこれを実現できます。merge() はすべての項目を 1 つの配列に追加し、unique() はその配列から重複を削除します。

http://api.jquery.com/jQuery.merge/

http://api.jquery.com/jQuery.unique/

于 2013-07-06T06:31:03.257 に答える