2017-01-25 5 views
3

私はこのような2つの配列を持っています。最初の配列はcustomFieldsあり、長さは、第二つfieldある2オブジェクトの2つの配列を比較する

var customFields = [ 
    { 
     "$$hashKey":"object:259", 
     "fields":[ 

     ], 
     "id":0.84177744416334, 
     "inputType":"number", 
     "labelShown":"item", 
     "type":"textBox", 
     "value":"222222" 
    }, 
    { 
     "$$hashKey":"object:260", 
     "fields":[ 
     "as", 
     "dd", 
     "asd" 
     ], 
     "id":0.51091342118417, 
     "inputType":"", 
     "labelShown":"labels", 
     "type":"selectBox", 
     "value":"dd" 
    } 
] 

であり、長さが3

var field = [ 
    { 
     "fields":[ 

     ], 
     "id":0.84177744416334, 
     "inputType":"number", 
     "labelShown":"item", 
     "type":"textBox" 
    }, 
    { 
     "fields":[ 
     "as", 
     "dd", 
     "asd" 
     ], 
     "id":0.51091342118417, 
     "inputType":"", 
     "labelShown":"labels", 
     "type":"selectBox" 
    }, 
    { 
     "fields":[ 

     ], 
     "id":0.32625015743856, 
     "inputType":"text", 
     "labelShown":"sample", 
     "type":"textBox" 
    } 
] 

両方のアレイは動的であり、iはidフィールドによってこれらの配列を比較し、customFieldsに不足しているオブジェクトを追加する必要があります配列fieldから配列。どのように私は2つのループなしでこれを行うことができますループ内のループ。最も効率的な方法は何ですか?ありがとうございました !!!!

+1

Basiclyあなたは、単一のイテレータでこれを達成することはできません。どの反復機能を使用する場合でも、ネストされた構造を反復するには常にネストされたメソッドが必要です。 – Teemu

+0

オブジェクトは常に同じ順序になっていますか? – cbass

+0

私が期待していたように、マップしたり答えを減らしたりしています... :)とにかく、どちらかといえば、フードの下にループがあります。 2つの普通の、explicite、ループ、imhoには何も間違っていません。 :) – sinisake

答えて

3

あなたは望ましい結果を得るためにreduce()find()を使用することができます。

var customFields = [{"$$hashKey":"object:259","fields":[],"id":0.84177744416334,"inputType":"number","labelShown":"item","type":"textBox","value":"222222"},{"$$hashKey":"object:260","fields":["as","dd","asd"],"id":0.51091342118417,"inputType":"","labelShown":"labels","type":"selectBox","value":"dd"}]; 
 
var field = [{"fields":[],"id":0.84177744416334,"inputType":"number","labelShown":"item","type":"textBox"},{"fields":["as","dd","asd"],"id":0.51091342118417,"inputType":"","labelShown":"labels","type":"selectBox"},{"fields":[],"id":0.32625015743856,"inputType":"text","labelShown":"sample","type":"textBox"}] 
 

 
var result = field.reduce(function(r, e) { 
 
    var f = customFields.find(el => e.id == el.id) 
 
    r.push(f ? f : e) 
 
    return r; 
 
}, []) 
 

 
console.log(result)

+0

ありがとう。 reduceメソッドから渡された合計と現在の値が正しく理解できれば。しかし、 'find'メソッドの内部で何が起きるかを明確にすることができます –

+0

確かに、フィールドの現在の要素と同じidを持つcustomFieldsの要素、つまり' e'を探しています。そして、それが見つかった場合、それはその要素を返します。この場合はそのオブジェクト –

+0

がいいです。これは私が '=>'演算子がjavascriptで値を代入するのに使われたのを初めて見たときです。すべてのことをはじめてお待ちください –

1

ネストループのないソリューションです。最初に、customFieldsアレイのIDを含むルックアップテーブルが生成される。次にfieldアレイが横断され、欠けている各オブジェクトがcustomFieldsアレイに追加されます。ルックアップテーブルは、可能な重複を処理するために更新されています。

var lut = customFields.map(function(obj) { 
    return obj.id; 
}); 
field.forEach(function(obj) { 
    if (lut.indexOf(obj.id) == -1) { 
    customFields.push(obj); 
    lut.push(obj.id); 
    } 
}); 

コメントで述べたように、私の最初の提案はindexOfに複雑さを隠しました。

ここでは、IDルックアップのオブジェクトプロパティに依存する代替アプローチがあります。これは、リニア検索より優れている可能性があります。 lutは、IDとcustomFieldsの配列インデックスとの関連付けを維持します。

var lut = customFields.reduce(function(t, obj, i) { 
    t[obj.id] = i; 
    return t; 
}, {}); 
field.forEach(function(obj) { 
    if (undefined === lut[obj.id]) { 
    lut[obj.id] = customFields.push(obj) - 1; 
    } 
}); 
+0

customFieldsがfieldsよりも大きければ...? – Legends

+0

OPは大文字小文字を指定していませんでした。これは 'customFields'に' field'配列に存在しない項目があるかどうかにかかわらず、_missing_項目を 'customFields'に追加するだけです。 – Joe

+1

'indexOf'はこのコードのネストされた反復です。 )。 – Teemu