2016-03-20 9 views
0

重複オブジェクトを結合してその数量を追加するためにこの関数を書いています。javascriptのsome()関数で使用されるオブジェクトへのアクセス

数量を増やすことに問題があります。

function removeDuplicates (input){ 

    var new_array = []; 

    input.forEach(function(unmerged){ 
     if(new_array.some(item => item.model === unmerged.model)){ 
      item.quantity += unmerged.quantity; ////this throws error 
     } else { 
      new_array.push(unmerged); 
     } 
    }); 

    return new_array; 
}; 

「アイテム」はsome()関数内で作成され使用され、アクセスできなくなったとします。どのように私はそのプロパティを編集できるようにこの機能を修正することができますか?

例:関数の前

:機能の後

var product_array = [ 
    {model:1, quantity:3}, 
    {model:1, quantity:2}, 
    {model:2, quantity:1} 
]; 

var product_array = [ 
    {model:1, quantity:5}, 
    {model:2, quantity:1} 
] 
+0

あなたの配列の例は前/後に追加することはできますか? – Andy

+0

@Andy例を追加しました。 – Suavocado

+0

'item'は' .some() 'の外で定義されていません。同じ 'item 'の' quantity'を自分自身に追加する目的は何ですか?期待される結果は何ですか? – guest271314

答えて

1

あなたは正しいです、項目は矢印のみの関数スコープの内部にアクセスできるようになります。

アンダースコア(またはロダッシュ).find関数を使用できます。例えば

:あなたはまた、ES5のためにそれ

var item = new_array.find(elem => elem.model ===unmerged.model); 
+0

2番目のオプションは美しく機能しますが、何らかの理由でlodashのバージョンが見えません。 – Suavocado

+0

さらに良いパターンはレデューサーです。 – okonetchnikov

+0

私はlodashで最初のオプションを試しましたが、それは私にとって完璧に機能します。プロジェクトにlodashを追加してもよろしいですか?とにかく、あなたがes6を使っているなら、私は第二のオプションをお勧めします、最初のものはes5でやっている簡単な方法です。 – kutomer

0

ためES6新しい配列機能を使用することができます

var item = _.find(new_array, {model : unmerged.model}); 
if (item) { 
    item.quantity += unmerged.quantity; 
} 

は、これが最もエレガントなソリューションではありませんが、あなたはこのようにそれを行うことができます。

function comparator(obj1, obj2) { 
    if (obj1.model < obj2.model) return -1; 
    if (obj1.model > obj2.model) return 1; 
    return 0; 
} 

function combineDuplicates(arr, comparator) { 
    arr.sort(comparator); 

    for (var i = 0; i < arr.length - 1; i++) { 
    while (arr[i + 1] !== undefined && arr[i].model === arr[i + 1].model) { 
     arr[i].quantity += arr[i + 1].quantity; 
     arr.splice(i + 1, 1); 
    } 
    } 

    return arr; 
} 

基本的には、配列をソートしてループします。重複の量を追加し続け、重複を削除し続ける2番目のループがあります。あまり効率的ではありませんが、機能します。

var product_array = [ 
    {model:1, quantity:3}, 
    {model:1, quantity:2}, 
    {model:2, quantity:1}, 
    {model:1, quantity:10}, 
    {model:1, quantity:10}, 
    {model:1, quantity:10}, 
    {model:2, quantity:5} 
]; 

var new_product_array = combineDuplicates(product_array, comparator); 
console.log(new_product_array); // [ { model: 1, quantity: 35 }, { model: 2, quantity: 6 } ] 
1

あなたはスコープでであることを変数にアイテムを割り当て、それを使用することができます。

input.forEach(function(unmerged){ 
    var current; 
    if(new_array.some(item => {current = item; return item.model === unmerged.model})){ 
    current.quantity += unmerged.quantity; ////this throws error 
    } else { 
    new_array.push(unmerged); 
    } 
}); 
0

あなたとしてforEachループ内thisを使用することができマージのための一時オブジェクト。

function removeDuplicates(input) { 
 
    var new_array = []; 
 
    input.forEach(function (unmerged) { 
 
     if (!this[unmerged.model]) { 
 
      this[unmerged.model] = unmerged; 
 
      new_array.push(unmerged); 
 
      return; 
 
     } 
 
     this[unmerged.model].quantity += unmerged.quantity; 
 
    }, {}); 
 
    return new_array; 
 
}; 
 

 
var product_array = [{ model: 1, quantity: 3 }, { model: 1, quantity: 2 }, { model: 2, quantity: 1 }], 
 
    result = removeDuplicates(product_array); 
 

 
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');

関連する問題