9

このオブジェクトを、製品名と平均価格を含むオブジェクトだけに縮小したいと考えています。それを行う最も速い方法は何ですか?

var foo = { group1: [
        {
            name: "one",
            price: 100
        },
        {
            name: "two",
            price: 100
        }],
       group2: [
        {
            name: "one",
            price: 200
        },
        {
            name: "two",
            price: 200
        }],
       group3: [
        {
            name: "one",
            price: 300
        },
        {
            name: "two",
            price: 300
        }]
      }

その結果

var foo2 = [{  
               name: 'one',  
               price: 200
            },{
               name: 'two', 
               price: 200
            }];

ありがとう!

4

3 に答える 3

21

エヴァンのパレードに雨が降るわけではありませんが、もう少し短い代替案があります ;)

result = _.chain(original)
  .flatten()
  .groupBy(function(value) { return value.name; })
  .map(function(value, key) {
    var sum = _.reduce(value, function(memo, val) { return memo + val.price; }, 0);
    return {name: key, price: sum / value.length};
  })
  .value();

実際に見てみましょう: http://plnkr.co/edit/lcmZoLkrlfoV8CGN4Pun?p=preview

于 2013-10-26T02:26:17.310 に答える
5

レッドマラードのソリューションはとても気に入っていますが、少しゴルフをしたかったのです。

Underscore には関数が含まれていませんが、 mixinsumを追加することで、非常に洗練された関数式を記述できます。sumこの関数は、underscore-contribs リポジトリのaddとして知られています。

次に、次のように記述できます。

// Somewhere in the initialization of the program
_.mixin({
  sum : function (arr) {
     return _.reduce(arr, function (s, x) { return s + x;}, 0);
  }
});
result = _.chain(original)
  .flatten()
  .groupBy('name') // shorthand notation
  .map(function (value, key) {
      var sum = _.chain(value).pluck('price').sum().value();
      return { name: key, price: sum / value.length}; 
  })
  .value();

http://plnkr.co/edit/ul3odB7lr8qwgVIDOtM9

avgしかし、ツールベルトを拡張するための mixin を作成することもできます:

// Somewhere in the initialization of the program
_.mixin({
  sum : function (arr) {
     return _.reduce(arr, function (s, x) { return s + x;}, 0);
  },
  avg : function (arr) {
     return _.sum(arr)/arr.length;
  }
});
result = _.chain(original)
  .flatten()
  .groupBy('name') // shorthand notation
  .map(function (value, key) {
      return { name: key, price: _.avg(value)}; 
  })
  .value();
于 2014-02-20T11:55:13.357 に答える
1

編集:これは今のところ残しておきますが、_.flattenを完全に忘れていたので、redmallard's got a much better answer .

製品名がすでにわかっていて、それらがすべてのグループに表示されている場合は、次の方法ですべてをすばやく行うことができます。

var productAveragePrices = function ( groups, names ) {
  return _.map( names, function ( name ) {
    var product = { name: name }, productPricesSum = 0;
    _.each( groups, function ( group ) {
      productPricesSum += ( _.findWhere( group, product ).price );
    });
    product.price = productPricesSum / _.size( groups );
    return product;
  });
};
var foo2 = productAveragePrices = function ( foo, ['one', 'two'] );

これをまとめると、グループに異なる製品がある場合でも機能するはずです (たとえば、1 番目、2 番目、4 番目のグループでは「1」、1 番目と 3 番目のグループでは「2」)。

var productPriceReducer = function( memo, group ) {
  _.each( group, function( product ) {
    // Grabs the current product from the list we're compiling
    var memoProduct = _.findWhere( memo, { name: product.name });
    if ( !memoProduct ) {
      // If the product doesn't exist, creates a holder for it and its prices
      memoProduct = {
        name: product.name,
        prices: [ product.price ]
      };
      memo.push( memoProduct );
    } else {
      // Otherwise, it just adds the prices to the existing holder.
      memoProduct.prices.push( product.price );
    }
  });
  return memo;
};

// This gets us a list of products with all of their prices across groups
var productPrices = _.reduce( foo, productPriceReducer, [] );

// Then reducing to the average is pretty simple!
var productAveragePrices = _.map( productPrices, function ( product ) {
  var sumPrices = _.reduce( product.prices, function ( memo, price ) {
    return memo + price;
  }, 0 );
  return {
    name: product.name,
    price: sumPrices / product.prices.length
  };
});

カウンターを使用して価格を合計する 1 つの関数で上記を実行することもできますが、この方法では、標準偏差を取得したりモードを見つけたりする場合に備えて、価格も取得できます。

于 2013-10-25T17:11:08.443 に答える