查找重复的obj属性并返回最低计数属性

时间:2018-07-01 23:45:53

标签: javascript dictionary ecmascript-6 reduce

让我们说我有一个看起来像这样的数组:

[
{count: 1, category: 4},
{count: 2, category: 4},
{count: 3, category: 2},
{count: 4, category: 2},
{count: 5, category: 8},
{count: 6, category: 8},
{count: 7, category: 1},
{count: 8, category: 1},
{count: 9, category: 1}
{count: 10, category: 8},
...
]

我想要的是从每个类别中找到最少的计数,然后返回一个新的对象数组。我可以使用一个简单的旧循环轻松地做到这一点,但我想使用map()。reduce或其他一些新的func技术。

4 个答案:

答案 0 :(得分:2)

有很多方法可以做到这一点。一种是:

function filterLowestCounts(a) {
  const lowestCountsByCategory = a.reduce(
    (result, { count, category }) => ({
      ...result,
      [category]: Math.min(count, result[category] || Number.MAX_SAFE_INTEGER)
    }),
    {}
  )

  return Object.entries(lowestCountsByCategory).map(
    ([category, count]) => ({ count, category: Number(category) })
  )
}

这样称呼它:

filterLowestCounts([
  {count: 1, category: 4},
  {count: 2, category: 4},
  {count: 3, category: 2},
  {count: 4, category: 2},
  {count: 5, category: 8},
  {count: 6, category: 8},
  {count: 7, category: 1},
  {count: 8, category: 1},
  {count: 9, category: 1},
  {count: 10, category: 8},
])

结果:

[
  {count: 7, category: 1},
  {count: 3, category: 2},
  {count: 1, category: 4},
  {count: 5, category: 8},
]

答案 1 :(得分:2)

看起来有些混乱,但这将是一种使用串联和嵌套的数组函数过滤,映射和归约的方法,在一行中完成此操作:

let array = [
{count: 1, category: 4},
{count: 2, category: 4},
{count: 3, category: 2},
{count: 4, category: 2},
{count: 5, category: 8},
{count: 6, category: 8},
{count: 7, category: 1},
{count: 8, category: 1},
{count: 9, category: 1},
{count: 10, category: 8}
]

let result = array.filter((value, index, self)=>{
     return self.findIndex((innerValue)=>{
         return innerValue.category == value.category}) === index;
 }).map((item)=>{
     return { count: array.filter((innerItem)=>{
         return innerItem.category == item.category
        }).reduce((min, item)=>{
         return (item.count < min) ? item.count : min; }).count, category: item.category};
 });
 
 console.log(result);

答案 2 :(得分:2)

使用Array#reduce()创建类别为键的对象并将对象作为值的对象,然后使用Object#values()获取数组

const res= Object.values(
   data.reduce((acc, {count, category}) => {
      const o = acc[category] || (acc[category] = {count, category});
      o.count = Math.min(o.count, count);   
      return acc;
    },{})
);

console.log(JSON.stringify(res))
<script>
var data= [
{count: 1, category: 4},
{count: 2, category: 4},
{count: 3, category: 2},
{count: 4, category: 2},
{count: 5, category: 8},
{count: 6, category: 8},
{count: 7, category: 1},
{count: 8, category: 1},
{count: 9, category: 1},
{count: 10, category: 8}

]
</script>

答案 3 :(得分:0)

var list = [
{count: 1, category: 4},
{count: 2, category: 4},
{count: 3, category: 2},
{count: 4, category: 2},
{count: 5, category: 8},
{count: 6, category: 8},
{count: 7, category: 1},
{count: 8, category: 1},
{count: 9, category: 1},
{count: 10, category: 8}
];

function groupAndGetMin(list, keyGetter, valueGetter) {
    const map = new Map();
    list.forEach((item) => {
        const key = keyGetter(item);
        const value = valueGetter(item);
        const o = map.get(key);
        if (!o) {
            map.set(key, item.count);
        } else {
            map.set(key, Math.min(o, value));
        }
    });
    return map;
}
var result = groupAndGetMin(list, l => l.category, i => i.count);

//这将返回Map(4){4 => 1,2 => 3,8 => 5,1 => 7}