使用lodash进行分组

时间:2017-11-21 14:12:21

标签: javascript lodash

我有一个对象数组如下:

var data = [
  {
    "count": 1, 
    "make": "ALFA ROMEO", 
    "model": "GIULIETTA DIESEL - 2010"
  }, 
  {
    "count": 2, 
    "make": "AUDI", 
    "model": "A1 DIESEL"
  }, 
  {
    "count": 1, 
    "make": "AUDI", 
    "model": "A1 SPORTBACK DIESEL"
  }, 
  {
    "count": 2, 
    "make": "AUDI", 
    "model": "A3 DIESEL - 2012"
  }, 
  {
    "count": 3, 
    "make": "Volkswagen", 
    "model": "Golf"
  }, 
  {
    "count": 3, 
    "make": "Ford", 
    "model": "Escord"
  }, 
  {
    "count": 2, 
    "make": "Opel", 
    "model": "Zafira"
  }
]

我希望通过group by make,然后获得最高计数的三个品牌,其余的我将作为其他品牌展示。

例如我想得到:

var result = [
    {
       "brand": "Audi",
       "count": 5
     },
     {
       "brand": "Volkswagen",
       "count": 3
     },
     {
       "brand": "Ford",
       "count": 3
     },
     {
       "brand": "Other",
       "count": 3
     }
]

我不知道如何开始。有什么帮助吗?

3 个答案:

答案 0 :(得分:2)

您可以使用lodash groupBysumBy

的组合来实现这一目标
var result = _.chain(data)
        .groupBy("make")
        .map( (element, id) => ({
            make: id,
            count: _.sumBy(element, 'count'),
        }))
        .value();

console.log(result);

[
  {
    "make": "ALFA ROMEO",
    "count": 1
  },
  {
    "make": "AUDI",
    "count": 5
  },
  {
    "make": "Volkswagen",
    "count": 3
  },
  {
    "make": "Ford",
    "count": 3
  },
  {
    "make": "Opel",
    "count": 2
  }
]

答案 1 :(得分:1)

使用lodash

启动lodash链。使用make _.groupBy(),然后_.map()结果,_.sumBy() count属性。使用_.values()转换回数组,使用_.orderBy()降序排序,然后使用_.value()完成链接。 Split将结果分成2个数组,并使用reduce:

对第2个数组(lowset计数)求和



var data = [{"count":1,"make":"ALFA ROMEO","model":"GIULIETTA DIESEL - 2010"},{"count":2,"make":"AUDI","model":"A1 DIESEL"},{"count":1,"make":"AUDI","model":"A1 SPORTBACK DIESEL"},{"count":2,"make":"AUDI","model":"A3 DIESEL - 2012"},{"count":3,"make":"Volkswagen","model":"Golf"},{"count":3,"make":"Ford","model":"Escord"},{"count":2,"make":"Opel","model":"Zafira"}];

var counts = _(data)
  .groupBy('make')
  .map(function(g, key) { return {
      make: key,
      count: _.sumBy(g, 'count')
  };})
  .values()
  .orderBy('count', 'desc')
  .value();
  
var result = counts.slice(0, 3).concat({
  brand: 'other',
  count: counts.slice(3).reduce(function(s, { count }) { return s + count; }, 0)
})
  
console.log(result);

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

使用ES6

使用Array#reduce进行迭代,将所有make count值收集到Map中的对象,然后获取map values iteratorspread以获取数组,并排序降。 Split将结果分成2个数组,并使用reduce:

对第2个数组(lowset计数)求和

&#13;
&#13;
const data = [{"count":1,"make":"ALFA ROMEO","model":"GIULIETTA DIESEL - 2010"},{"count":2,"make":"AUDI","model":"A1 DIESEL"},{"count":1,"make":"AUDI","model":"A1 SPORTBACK DIESEL"},{"count":2,"make":"AUDI","model":"A3 DIESEL - 2012"},{"count":3,"make":"Volkswagen","model":"Golf"},{"count":3,"make":"Ford","model":"Escord"},{"count":2,"make":"Opel","model":"Zafira"}];

const counts = [...data.reduce((m, { make, count }) => {
  const item = m.get(make) || { make, count: 0 };
  
  item.count += count;

  return m.set(make,  item);
}, new Map()).values()].sort((a, b) => b.count - a.count);

const result = counts.slice(0, 3).concat({
  brand: 'other',
  count: counts.slice(3).reduce((s, { count }) => s + count, 0)
})

console.log(result);
&#13;
&#13;
&#13;

答案 2 :(得分:1)

使用普通的Javascript,您可以使用哈希表来收集相同的make并对结果数组进行排序。稍后添加结果集末尾的所有计数,直到数组达到所需长度。

var data = [{ count: 1, make: "ALFA ROMEO", model: "GIULIETTA DIESEL - 2010" }, { count: 2, make: "AUDI", model: "A1 DIESEL" }, { count: 1, make: "AUDI", model: "A1 SPORTBACK DIESEL" }, { count: 2, make: "AUDI", model: "A3 DIESEL - 2012" }, { count: 3, make: "Volkswagen", model: "Golf" }, { count: 3, make: "Ford", model: "Escord" }, { count: 2, make: "Opel", model: "Zafira" }],
    hash = Object.create(null),
    result = [];

data.forEach(function (car) {
    if (!hash[car.make]) {
        hash[car.make] = { make: car.make, count: 0 };
        result.push(hash[car.make]);
    }
    hash[car.make].count += car.count;
});

result.sort(function (a, b) {
    return b.count - a.count;
});

while (result.length > 4) {
    result.push({ make: 'Other', count: result.pop().count + result.pop().count });
}

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