web-dev-qa-db-ja.com

オブジェクトの配列内のオブジェクトプロパティを単一のオブジェクトLodashに合計する

私はこれを正しくしようとしていて、問題を抱えていたので、もっと経験のある人に質問するべきだと考えました私はオブジェクトと呼ばれるアイテムの配列を持っていますが、これはアイテムと呼ばれ、配列内のさまざまなオブジェクトのプロパティのいくつかを合計し、最後にそれらを合計する必要があります。ユーザーはいくつかの選択を行うことができ、配列で選択されたプロパティのみを合計する必要があるので、lodashで_.pick関数を使用することを考えました。 items配列には最大1000の項目を含めることができるので、可能であれば1つのループでそれを実行します。次に例を示します。

var items = [
{'lightBlue':4, 'darkBlue':2, 'red':4, 'orange':6, 'purple':7},
{'lightBlue':6, 'darkBlue':5, 'red':1, 'orange':2, 'purple':3},
{'lightBlue':2, 'darkBlue':4, 'red':3, 'orange':4, 'purple':9}
]

var userSelectedColors = ['lightBlue', 'darkBlue'];

私が見たいのは、すべての青の合計です:

var summedUp = [{'lightBlue':12, 'darkBlue':11}];

次に、結果を合計して合計を取得します

var totalCount = 23

これをロダッシュで取得するための最良かつ高性能な方法は何ですか? userSelectedColorsの配列は、1または色の任意の組み合わせになります。

例を挙げてください、ありがとうございます!

10
Shokwave

使用する - _.sumBy

var totalCount = _.sumBy(userSelectedColors, _.partial(_.sumBy, items));
var items = [
  { 'lightBlue': 4, 'darkBlue': 2, 'red': 4, 'orange': 6, 'purple': 7 },
  { 'lightBlue': 6, 'darkBlue': 5, 'red': 1, 'orange': 2, 'purple': 3 },
  { 'lightBlue': 2, 'darkBlue': 4, 'red': 3, 'orange': 4, 'purple': 9 }
], userSelectedColors = ['lightBlue', 'darkBlue'];

var totalCount = _.sumBy(userSelectedColors, _.partial(_.sumBy, items));

console.log(totalCount);
<script src="https://cdn.jsdelivr.net/lodash/4.13.1/lodash.min.js"></script>

展開すると、次のようになります。

var totalCount = _.sumBy(userSelectedColors, function(prop) {
    return _.sumBy(items, prop);
});

Lodashがなければ、よりパフォーマンスの高いソリューションは次のようになります。

var totalCount = items.reduce(function(total, obj) {
    return total + userSelectedColors.reduce(function(total, prop) {
        return total + obj[prop];
    }, 0);
}, 0);
var items = [
  { 'lightBlue': 4, 'darkBlue': 2, 'red': 4, 'orange': 6, 'purple': 7 },
  { 'lightBlue': 6, 'darkBlue': 5, 'red': 1, 'orange': 2, 'purple': 3 },
  { 'lightBlue': 2, 'darkBlue': 4, 'red': 3, 'orange': 4, 'purple': 9 }
], userSelectedColors = ['lightBlue', 'darkBlue'];

var totalCount = items.reduce(function(total, obj) {
    return total + userSelectedColors.reduce(function(total, prop) {
        return total + obj[prop];
    }, 0);
}, 0);

console.log(totalCount);
<script src="https://cdn.jsdelivr.net/lodash/4.13.1/lodash.min.js"></script>
17
4castle

効率の面では、これは配列全体で1回しか繰り返されないため、打ち勝つのは難しいと思いますが、@ 4castleが採用したようなアプローチほど簡潔ではありません。 (また、1000アイテムのみの場合でも、パフォーマンスの違いに気付くことはありません。)

var items = [
    {'lightBlue':4, 'darkBlue':2, 'red':4, 'orange':6, 'purple':7},
    {'lightBlue':6, 'darkBlue':5, 'red':1, 'orange':2, 'purple':3},
    {'lightBlue':2, 'darkBlue':4, 'red':3, 'orange':4, 'purple':9}
]

var userSelectedColors = ['lightBlue', 'darkBlue'];

var sums = {};

_.each(items, function (item) {
    _.each(userSelectedColors, function (color) {
        sums[color] = (sums[color] || 0) + item[color];
    });
});

console.log('Summary: ', sums);

console.log('Grand total: ', _.sum(_.values(sums)));

出力:

Summary:  { lightBlue: 12, darkBlue: 11 }
Grand total:  23
4
user94559