2016-11-17 5 views
0

私はいくつかのオブジェクトを以下のような形にしています。Javascriptはキーに基づいて2つのオブジェクトを結合します

[{ 
    product: 'ABC', 
    productId: 'AB123', 
    batch: 'BA1', 
    price: '12' 
}, { 
    product: 'ABC', 
    productId: 'AB123', 
    batch: 'BA2', 
    price: '15' 
}, { 
    product: 'XYZ', 
    productId: 'AB124', 
    batch: 'XY1', 
    price: '124' 
}] 

Iは、鍵ペア(product、及びproductId)は以下の形式で、mathcedされている場合、アレイ内の1つのオブジェクトにオブジェクトをマージします。

[{ 
    product: 'ABC', 
    productId: 'AB123', 
    batch: ['BA1', 'BA2'], 
    price: ['12', '15'] 
}, { 
    product: 'XYZ', 
    productId: 'AB124', 
    batch: 'XY1', 
    price: '124' 
}] 

私はロダッシュまたは純粋なjavascriptでどうすればいいですか?

+2

は、あなたの研究を共有するすべての人を助けます。あなたが試したことと、それがあなたのニーズを満たさなかった理由を教えてください。これは、時間をかけて自分自身を助けようとしていることを示しています。明白な回答を繰り返さないようにしてくれています。そして、より具体的で適切な答えを得ることができます。 – Cerbrus

+0

期待される結果オブジェクトには、さまざまな構造が含まれています。製品のエントリが複数ある場合は、バッチと価格の配列がありますが、配列がない場合は、単一の値しか期待できません。結果のオブジェクトが共通の形式に従うべきではありませんか?つまり、バッチ/価格の場合は常に配列、価格とバッチのオブジェクトを含む配列の場合は1つの配列で、どのバッチがどの価格に属するかを知ることができます。 – Nope

答えて

3

この提案では、指定されたデータは変更されません。

最初は単一のデータで新しいオブジェクトを作成し、後でさらにデータをグループ化する場合はbatchpriceの配列を使用します。

var data = [{ product: 'ABC', productId: 'AB123', batch: 'BA1', price: '12' }, { product: 'ABC', productId: 'AB123', batch: 'BA2', price: '15' }, { product: 'XYZ', productId: 'AB124', batch: 'XY1', price: '124'}], 
 
    merged = []; 
 

 
data.forEach(function (a) { 
 
    if (!this[a.productId]) { 
 
     this[a.productId] = { product: a.product, productId: a.productId, batch: a.batch, price: a.price }; 
 
     merged.push(this[a.productId]); 
 
     return; 
 
    } 
 
    if (!Array.isArray(this[a.productId].batch)) { 
 
     this[a.productId].batch = [this[a.productId].batch]; 
 
    } 
 
    if (!Array.isArray(this[a.productId].price)) { 
 
     this[a.productId].price = [this[a.productId].price]; 
 
    } 
 
    this[a.productId].batch.push(a.batch); 
 
    this[a.productId].price.push(a.price); 
 
}, Object.create(null)); 
 

 
console.log(merged);

+2

今回はあなたからのライナーはいませんか? :D – fafl

+0

@fafl、よろしく! –

+1

あなたは素晴らしいです! @NinaScholz –

0

それが読めることがありますか?

function mergeSimilar(arr, arrayProps) { 
 
    // transform the array into a map object 
 
    return _(arr).transform(function(result, item) { 
 
    
 
    // create a temp id that includes the product and productId 
 
    var id = item.product + item.productId; 
 
    
 
    // merge the existing item with a new item 
 
    result[id] = _.mergeWith(result[id] || {}, item, function(objValue, srcValue, key) { 
 
     
 
     // if a value exists, and it's one of the request keys, concat them into a new array 
 
     if (!_.isUndefined(objValue) && _.includes(arrayProps, key)) { 
 
     return [].concat(objValue, srcValue); 
 
     } 
 
    }); 
 
    }, {}) 
 
    .values() // get the values from the map object 
 
    .value(); 
 
} 
 

 
var arr = [{ 
 
    product: 'ABC', 
 
    productId: 'AB123', 
 
    batch: 'BA1', 
 
    price: '12' 
 
}, { 
 
    product: 'ABC', 
 
    productId: 'AB123', 
 
    batch: 'BA2', 
 
    price: '15' 
 
}, { 
 
    product: 'XYZ', 
 
    productId: 'AB124', 
 
    batch: 'XY1', 
 
    price: '124' 
 
}]; 
 

 
var result = mergeSimilar(arr, ['batch', 'price']); 
 

 
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.2/lodash.min.js"></script>

0

あなたは_.transform()_.mergeWith()とlodashのチェーンを使用して配列に類似したオブジェクトをマージすることができます重複を取り除くそれとは別に、uniqWithはオブジェクト自体へのアクセスを許可しますので、好きなようにそれらを改ざんすることができます。

この場合、重複が見つかると、元のオブジェクトの配列にバッチと価格を追加して、目的の結果を得ます。

var arr = [{ 
 
    product: 'ABC', 
 
    productId: 'AB123', 
 
    batch: 'BA1', 
 
    price: '12' 
 
}, { 
 
    product: 'ABC', 
 
    productId: 'AB123', 
 
    batch: 'BA2', 
 
    price: '15' 
 
}, { 
 
    product: 'XYZ', 
 
    productId: 'AB124', 
 
    batch: 'XY1', 
 
    price: '124' 
 
}]; 
 

 
function addToArray(val1, val2) { 
 
    return _.isArray(val1) ? val1.concat(val2) : [val1].concat(val2); 
 
} 
 

 
function modifyObjs(a, b) { 
 
    b.batch = addToArray(b.batch, a.batch); 
 
    b.price = addToArray(b.price, a.price); 
 
    return true; 
 
} 
 

 
function predicateAndModifier(a, b) { 
 
    return a.product === b.product && a.productId === b.productId && modifyObjs(a, b); 
 
} 
 

 
console.log(_.uniqWith(arr, predicateAndModifier));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.2/lodash.min.js"></script>

1

あなたは、コレクションをループに_.uniqWithを利用することができますし、取得:

var data = [{ 
    product: 'ABC', 
    productId: 'AB123', 
    batch: 'BA1', 
    price: '12' 
}, { 
    product: 'ABC', 
    productId: 'AB123', 
    batch: 'BA2', 
    price: '15' 
}, { 
    product: 'ABC', 
    productId: 'AB113', 
    batch: 'BA2', 
    price: 15 
}, { 
    product: 'XYZ', 
    productId: 'AB124', 
    batch: 'XY1', 
    price: '124' 
}] 
var unEs6 = function(x) { 
    if (x instanceof Map) { 
     var result = {} 
     for (let [key, value] of x.entries()) { 
      result[key] = unEs6(value); 
     } 
     return result; 
    } 
    else { 
     return x 
    } 
} 
JSON.stringify(unEs6(
    data 
     .map(
      row => (new Map().set(
       row.product, new Map().set(
        row.productId, new Map() 
         .set("batch", [row.batch]) 
         .set("price", [row.price]) 
        ) 
       ) 
      ) 
     ) 
     .reduce((a, b) => !a.has(b.keys().next().value) ? 
      new Map([...a, ...b]) : 
      !a.get(b.keys().next().value).has(b.get(b.keys().next().value).keys().next().value) ? 
       a.set(b.keys().next().value, new Map([ 
        ...a.get(b.keys().next().value), 
        ...b.get(b.keys().next().value) 
       ])) : 
       a.set(b.keys().next().value, a.get(b.keys().next().value).set(
        b.get(b.keys().next().value).keys().next().value, 
        new Map() 
         .set("batch", a.get(b.keys().next().value).get(b.get(b.keys().next().value).keys().next().value).get("batch") 
           .concat(b.get(b.keys().next().value).get(b.get(b.keys().next().value).keys().next().value).get("batch")) 
         ) 
         .set("price", a.get(b.keys().next().value).get(b.get(b.keys().next().value).keys().next().value).get("price") 
           .concat(b.get(b.keys().next().value).get(b.get(b.keys().next().value).keys().next().value).get("price")) 
         ) 
       )) 
     ) 
)) 
0

Lodash 4.17.2

_.reduce(data, function(result, item) { 
    var added = _.find(result, { 
     product: item.product, 
     productId: item.productId 
    }); 
    if (_.isObject(added)) { 
     //!! better to merge with new object and add result to array again to avoid mutable 
     added = _.mergeWith(added, item, function(addedVal, itemVal, key) { 
      if (key === 'product' || key === 'productId') { 
       return addedVal; 
      } 
      return _.concat(addedVal, itemVal); 
     }); 
     return result; 
    } 
    return _.concat(result, item); 
}, []); 
関連する問題