2017-09-19 6 views
0

私は解決しようとしてきたユニークな課題を持っています。JavaScript ES6は同じループ反復で配列にマップされる値の合計を得る

obj = 
    [ 
     {item: "Skirt", price: 290}, 
     {item: "Shoes", price: 300}, 
     {item: "Skirt", price: 450}, {item: "Jeans", price: 35} 
    ] 

私が所望の出力のように見えるように、それぞれの平均価格と重複するアイテムの数を取得するには、これをマッピングしています:

UPDATE:

obj = 
[ 
{ 
Skirt: 2, 
price: 370, //2 being the count of skirt items, 370 average price 
Jeans: 1, 
Price: 35, 
Shoes: 1, 
Price: 30 
} 
] 
私はこのようなオブジェクトを持っています

私はアイテムをマッピングするために、この機能を使用しています:

Av_price = function(values) { 
    let new_val = new Map(); 
     for (let x of values) 
     new_val.set([x["item"]], [(new_val.get(x["item"])|| 0) +1), (new_val.get(x["price"] || x["price"])/x["price"]]) 
return [...new_val.entries()]; 
}; 

問題は次のとおりです。私は、スカートと言ってアイテムの数を数えることができますが、第2の値をまっすぐに得ることができません。私はそれらをアイテムの合計数で分割することができます(この例では、スカートの場合は「2」です)。 このユニークな挑戦は、2週間私の心を震わせました。同じループ反復でマップされているすべてのスカートの数を取得し、平均価格を得るためにその数で価格の合計を割り算する方法はありますか?

私は大いに助けに感謝します!

答えて

2

あなたは同じ項目のハッシュテーブルを取得し、格納された値のうち、平均を構築することができます。結果のための変更されたデータ構造で

var data = [{ item: "Skirt", price: 290 }, { item: "Shoes", price: 300 }, { item: "Skirt", price: 450 }, { item: "Jeans", price: 35 }], 
 
    hash = Object.create(null), 
 
    result = []; 
 

 
data.forEach(function (o) { 
 
    var ref; 
 
    if (!hash[o.item]) { 
 
     hash[o.item] = [{ item: o.item }, [0, 0]] 
 
     result.push(hash[o.item]); 
 
    } 
 
    ref = hash[o.item][1]; 
 
    ref[1] = (ref[0] * ref[1] + o.price)/++ref[0]; 
 
}); 
 

 
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

、あなたはハッシュテーブルを省略し、直接結果オブジェクトを取るyould。

var data = [{ item: "Skirt", price: 290 }, { item: "Shoes", price: 300 }, { item: "Skirt", price: 450 }, { item: "Jeans", price: 35 }], 
 
    result = data.reduce(function (o, { item, price }) { 
 
     o[item] = o[item] || 0; 
 
     o[item + 'Price'] = (o[item] * (o[item + 'Price'] || 0) + price)/++o[item]; 
 
     return o; 
 
    }, {}); 
 

 
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

+0

あなたの答えは平均を含む完全な解決策を提供していると思いますが、@ Jared Smithのような構造でそれを行うことは可能ですか?有難うございます。 – Zafar

+0

希望の構造を更新しました。あなたは今それを見ていただけますか? – Zafar

1
let totalItems = obj.reduce((acc, {name, price}) => { 
    if (!acc[name]) { 
    acc[name] = 0; 
    acc[`${name}Price`] = price; 
    } 
    acc[name] += 1; 
    return acc; 
}, {}); 

ここでは、各アイテムの価格とそれぞれの合計数があります。 totalItemsオブジェクトは次のようになります。

{ 
    skirt: 6, 
    skirtPrice: 290, 
    shoes: 3, 
    shoesPrice: 300 
} 

などとなります。

+0

私は、そのシンプルさのこの回答が好き。それがうまくいってほしい。結果配列内に「未定義」と表示されます – Zafar

+0

これは関数内で実装しています: 'Av_price = function(obj){ let totalItems = obj.reduce((acc、{brand、sale_price})=> { if(!acc [brand]){ acc [brand] = 0; acc ['$ {brand} Price'] = sale_price; } acc [ブランド] + = 1; return acc; }、{}); }; ' – Zafar

+0

@Zafarあなたは' totalItems'を返していないので、もちろん戻り値は未定義になります。 'let totalItems = obj.reduce ...'の代わりに 'return obj.reduce ...'だけです。 –

1

Array#reduceを使用して、countと各アイテムの合計価格を含むマップを作成します。そして、要求された形式へのエントリにマップし、アレイ#マップ、それを広める:

const arr = [ 
 
    {item: "Skirt", price: 290}, 
 
    {item: "Shoes", price: 300}, 
 
    {item: "Skirt", price: 450}, 
 
    {item: "Jeans", price: 35} 
 
]; 
 

 
const Av_price = (values) => [... 
 
    new Map(values.reduce((map, { item, price }) => { 
 
    const o = map.get(item) || { sum: 0, count: 0 }; 
 
    o.count++; 
 
    o.sum += price; 
 

 
    return map.set(item, o); 
 
    }, new Map())) 
 
].map(([item, { count, sum }]) => [item, [count, sum/count]]); 
 

 
const result = Av_price(arr); 
 

 
console.log(result);

関連する問題