通过参数组合和分组javascript对象的最佳方法

时间:2017-01-24 19:55:48

标签: javascript

我在React的购物车页面上工作,基本上我需要按产品名称对订单进行分组并包含数量。

所以......如果我的产品阵列如下......

const items = [
  { title: 'Test', price: 1 },
  { title: 'Test', price: 1 },
  { title: 'Another Test', price: 3 },
]

我试图得到类似......

const expected = [
  { title: 'Test', price: 1, quantity: 2 },
  { title: 'Another Test', price: 3, quantity: 1 },
]

我尝试了一些不太适合我的方法,包括使用来自下划线的groupBy,但没有快乐!

这里是一个JS小提琴,我正在弄乱:https://jsfiddle.net/rL8y3Lh4/2/

5 个答案:

答案 0 :(得分:2)

您可以使用Map进行分组。



var items = [{ title: 'Test', price: 1 }, { title: 'Test', price: 1 }, { title: 'Another Test', price: 3 }],
    grouped = items.reduce((map => (r, a) => {
        if (!map.has(a.title)) {
            map.set(a.title, { title: a.title, price: a.price, quantity: 0 });
            r.push(map.get(a.title));
        }
        map.get(a.title).quantity++;
        return r;
    })(new Map), []);

console.log(grouped);

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




ES5,在哈希表上有一个闭包。



var items = [{ title: 'Test', price: 1 }, { title: 'Test', price: 1 }, { title: 'Another Test', price: 3 }],
    grouped = items.reduce(function (hash) {
        return function (r, a) {
            if (!hash[a.title]) {
                hash[a.title] = { title: a.title, price: a.price, quantity: 0 };
                r.push(hash[a.title]);
            }
            hash[a.title].quantity++;
            return r;
        };
    }(Object.create(null)), []);

console.log(grouped);

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




答案 1 :(得分:1)

在普通的javascript中,您可以使用reduce()执行此操作。

const items = [
  { title: 'Test', price: 1 },
  { title: 'Test', price: 1 },
  { title: 'Another Test', price: 3 }
]

var o = {}
var result = items.reduce(function(r, e) {
  if (!o[e.title]) {
    o[e.title] = e;
    o[e.title].quantity = 0;
    r.push(o[e.title])
  }
  o[e.title].quantity += 1;
  return r;
}, [])
console.log(result)

如果您想保存原始数据,还可以使用forEach()Object.assign()创建新对象。

const items = [
  { title: 'Test', price: 1 },
  { title: 'Test', price: 1 },
  { title: 'Another Test', price: 3 },
]


var result = []
items.forEach(function(e) {
  if (!this[e.title]) {
    this[e.title] = Object.assign({}, e, {quantity: 0})
    result.push(this[e.title])
  }
  this[e.title].quantity += 1
}, {})

console.log(result)

答案 2 :(得分:1)

您可以按产品名称/标题/ ID使用字典。循环遍历每个项目,添加新条目或递增现有条目的quantity

const items = [
  { title: 'Test', price: 1 },
  { title: 'Test', price: 1 },
  { title: 'Another Test', price: 3 }
];

let cart = {};
items.forEach(item => {
  if (cart[item.title]) {
    cart[item.title].quantity++;
  } else {
    cart[item.title] = {price: item.price, quantity: 1};
  }
});

console.log(cart);

这假设具有相同title s的项目具有相同的price s。

答案 3 :(得分:1)

应用Array.prototype.reduce函数的另一个简短版本:

var items = [{ title: 'Test', price: 1 },{ title: 'Test', price: 1 },{ title: 'Another Test', price: 3 }],    
    expected = [];

items.reduce(function (o, a) {  // grouping objects by 'title' attribute
  (o[a.title])? 
    ++o[a.title].quantity 
    : o[a.title] = expected[expected.push({title: a.title, price: a.price, quantity: 1}) - 1];
  return o;
}, {});

console.log(expected);

答案 4 :(得分:1)

如果您可以在项目中使用lodash库,我建议使用lodash unionBy



const items = [
      { title: 'Test', price: 1 },
      { title: 'Test', price: 1 },
      { title: 'Another Test', price: 3 },
    ]; 
  
  let items1 = _.map(items, function(o) {
    o.quantity = 1;
    return o;
  });

  result = _.unionWith(items1, function(a,b) {
  if(a.title === b.title) {
    b.quantity++;
  return true;
  }
  return false;  
  });

  console.log(result);

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
&#13;
&#13;
&#13;

希望这是你需要的