3

私は次のような配列を持っています。

[ { sku: 'TEA-BLCK', price: '10', quantity: '1' },
  { sku: 'TEA-ELGY', price: '10', quantity: '1' },
  { sku: 'TEA-CHAI', price: '10', quantity: '1' },
  { sku: 'TEA-GREN', price: '10', quantity: '1' },
  { sku: 'TEA-ELGY', price: '10', quantity: '1' },
  { sku: 'TEA-MINT', price: '10', quantity: '1' } ]

このようにする必要があります

[ { sku: 'TEA-BLCK', price: '10', quantity: '1' },
  { sku: 'TEA-ELGY', price: '10', quantity: '2' },
  { sku: 'TEA-CHAI', price: '10', quantity: '1' },
  { sku: 'TEA-GREN', price: '10', quantity: '1' },
  { sku: 'TEA-MINT', price: '10', quantity: '1' } ]

これまでに、をreduce使用してこの関数を作成しunderscore.jsました。

var reduce = function(){
    return _.reduce(line_items, function(quant, item) {
        quant[item.sku] = (typeof(quant[item.sku]) !== "undefined") ? quant[item.sku] : 0 ;
        quant[item.sku] = parseFloat(item.quantity) + quant[item.sku];
        return quant;
    }, {});
}

これは次のことを吐き出します。

{ 'TEA-BLCK': 1,
  'TEA-ELGY': 1,
  'TEA-CHAI': 2,
  'TEA-GREN': 1,
  'TEA-MINT': 1 }

これは削減するのに良い仕事ですか?どうすれば思い通りにできますか?

4

6 に答える 6

3

次のようなことを試してください:

var line_items = [
    { sku: 'TEA-BLCK', price: '10', quantity: 2 },
    { sku: 'TEA-ELGY', price: '10', quantity: 3 },
    { sku: 'TEA-CHAI', price: '10', quantity: 1 },
    { sku: 'TEA-GREN', price: '10', quantity: 1 },
    { sku: 'TEA-ELGY', price: '10', quantity: 1 },
    { sku: 'TEA-MINT', price: '10', quantity: 1 }
];

// Group items by sku.
var line_items_by_sku = _(line_items).groupBy(function (item) { return item.sku; });

// Get the new line_items array based on the grouped data.
line_items = _(line_items_by_sku).map(function (items) {
    var item = items[0];
    item.quantity = _.reduce(items, function(memo, item){ return memo + item.quantity; }, 0);
    return item;
});

この jsfiddleを参照してください。

于 2013-01-04T20:21:22.267 に答える
2

次のような単純なソリューションはどうでしょうか。

function reduce(array) {
    var out = [];
    var indexBySku = {};
    for (var i = array.length; i--;) {
        if (!indexBySku[array[i].sku]) {
            indexBySku[array[i].sku] = out.length;
            out.push(array[i]);
        } else {
            out[indexBySku[array[i].sku]].quantity -= -array[i].quantity;
        }
    }
    return out;
}

http://jsfiddle.net/waV6H/1

おそらくここで説明が必要なのは、加算ではなく負の値を減算する行だけです。「数量」の値は文字列であるため、これは単に文字列の連結を避けるためです。


不要な中かっことセミコロンを削除した、超凝縮バージョン... ただの楽しみです。順序と数量を文字列として保持し、数量 != 1 で機能します。

function reduce(array) {
    var out = [], indexBySku = {}, len = array.length, i, j
    for (i = 0; i < len; i++)
        (j = indexBySku[array[i].sku]) ?  
            out[j].quantity = out[j].quantity - -array[i].quantity + '' :
            indexBySku[array[i].sku] = out.push(array[i]) - 1
    return out
}
于 2013-01-04T20:21:26.207 に答える
1

これにより、ベネカスタの回答が更新され、1を超える数量が処理されます...しかし、数量を整数に変更する自由を取りました

http://jsfiddle.net/xjUDY/3/

var line_items = [
    { sku: 'TEA-BLCK', price: '10', quantity: 2 },
    { sku: 'TEA-ELGY', price: '10', quantity: 3 },
    { sku: 'TEA-CHAI', price: '10', quantity: 1 },
    { sku: 'TEA-GREN', price: '10', quantity: 1 },
    { sku: 'TEA-ELGY', price: '10', quantity: 1 },
    { sku: 'TEA-MINT', price: '10', quantity: 1 }
];

// Group items by sku.
var line_items_by_sku = _(line_items).groupBy(function (item) { return item.sku; });

// Get the new line_items array based on the grouped data.
line_items = _(line_items_by_sku).map(function (items) {
    var item = items[0];
    item.quantity = _.reduce(items, function(memo, item){ return memo + item.quantity; }, 0);
    return item;
});

document.write("<pre>"+JSON.stringify(line_items, null, " ")+"</pre>");
​
于 2013-01-04T22:01:31.193 に答える
1

パーティーに少し遅れましたが、とても楽しそうだったので..

JSON.stringify(
[ { sku: 'TEA-BLCK', price: '10', quantity: '1' },
  { sku: 'TEA-ELGY', price: '10', quantity: '1' },
  { sku: 'TEA-CHAI', price: '10', quantity: '1' },
  { sku: 'TEA-GREN', price: '10', quantity: '1' },
  { sku: 'TEA-ELGY', price: '10', quantity: '1' },
  { sku: 'TEA-MINT', price: '10', quantity: '1' } ].sort( function (a, b) {
   return a.sku < b.sku;
} ).reduce( function (a,v) {
   if ( !a[0] || a[0].sku !== v.sku  ) {
      a.unshift(v);
   } else {
      // notice the very inefficient str -> number -> str conversion
      a[0].quantity = 1*a[0].quantity + 1*v.quantity + '';
   }

   return a;
 }, []) );

ここでは、配列を事前に並べ替えてから、accumulator の先頭に要素を追加します。そしてGGGはすでに文字列について述べています。

http://jsfiddle.net/EqGUe/

于 2013-01-04T20:39:30.383 に答える
1

少し遅いですが、うまくいくのは楽しい http://jsbin.com/amazat/2/

line_items_reduced = _.map(reduce(), function(value, key) {
  var line_item = _.find(line_items, function(line_i){
    return (key === line_i.sku);
  });
  line_item.quantity = value;
  return line_item;
});
于 2013-01-04T21:24:52.267 に答える
0

技術的には、これが完全な答えです。弦から弦へ。申し訳ありません。

var line_items = [
    { sku: 'TEA-BLCK', price: '10', quantity: "2" },
    { sku: 'TEA-ELGY', price: '10', quantity: "3" },
    { sku: 'TEA-CHAI', price: '10', quantity: "1" },
    { sku: 'TEA-GREN', price: '10', quantity: "1" },
    { sku: 'TEA-ELGY', price: '10', quantity: "1" },
    { sku: 'TEA-MINT', price: '10', quantity: "1" }
];

// Group items by sku.
var line_items_by_sku = _(line_items).groupBy(function (item) { return item.sku; });

// Get the new line_items array based on the grouped data.
line_items = _(line_items_by_sku).map(function (items) {
    var item = items[0];
    item.quantity = _.reduce(items, function(memo, item){ return memo + parseFloat(item.quantity); }, 0);
    item.quantity = item.quantity.toString();
    return item;
});

document.write("<pre>"+JSON.stringify(line_items, null, " ")+"</pre>");
于 2013-01-04T22:19:37.853 に答える