【问题标题】:Count no of occurrence of each value in javascript计算javascript中每个值的出现次数
【发布时间】:2018-01-17 00:34:10
【问题描述】:

我最终以繁琐的循环来转换

[{Name: "Daniel Montes", color: "red"},
 {Name: "Daniel Montes", color: "red"},
 {Name: "Daniel Montes", color: "red"},
 {Name: "Michelle Aguirre", color: "red"},
 {Name: "Daniel Montes", color: "green"}
]

[
{Name: "Daniel Montes", green:1,red:3},
{Name: "Michelle Aguirre", green:0,red:1},
]

红色和绿色只是两种颜色,因此也可以进行硬编码。

实现它的最佳方法是什么? 我们在 lodash 上是否有任何东西或类似的东西?

【问题讨论】:

  • 显示您尝试过的内容。无法避免循环

标签: javascript arrays ecmascript-6 lodash


【解决方案1】:

var input = [{Name: "Daniel Montes", color: "red"},
{Name: "Daniel Montes", color: "red"},
{Name: "Daniel Montes", color: "red"},
{Name: "Michelle Aguirre", color: "red"},
{Name: "Daniel Montes", color: "green"}
];

function solve(list){
    var map = new Map();
    var entry = null;
    for(var item of list){
        if(!map.has(item.Name))
            map.set(item.Name, {Name: item.Name});

        entry = map.get(item.Name);

        if(entry.hasOwnProperty(item.color))
            entry[item.color] = entry[item.color] + 1;
        else
            entry[item.color] = 1;
    }
    return Array.from(map.values());
}

console.log(solve(input))

这是我为您的问题编写的快速解决方案。

【讨论】:

  • entry[item.color] = entry[item.color] + 1;可以改成++entry[item.color];
【解决方案2】:

另一种方法是使用reduce。如果使用基于固定属性Nameredgreen的模板对象,代码可以短一些。

以下两种解决方案都使用索引对象来跟踪命名对象在结果数组中的位置,类似于 pattpass 对 Map 的使用。如果特定名称具有该颜色,则第一个解决方案仅在解决方案中包含该颜色。第二种解决方案使用具有固定属性的模板对象,因此如果对象没有颜色,则它在结果中的值为 0。

通过动态跟踪颜色可以实现相同的结果,但需要有逻辑将零颜色添加到没有它们的对象(可能最后是一个循环)。

var input = [{Name: "Daniel Montes", color: "red"},
             {Name: "Daniel Montes", color: "red"},
             {Name: "Daniel Montes", color: "red"},
             {Name: "Michelle Aguirre", color: "red"},
             {Name: "Daniel Montes", color: "green"}
            ];

// Only add color if object has that color
function process0(data) {
  var index = Object.create(null);
  return input.reduce(function (acc, obj) {
    var name = obj.Name,
        color = obj.color;
  
    // If haven't seen name before, add to index and
    // default object to accumulator
    if (!index[name]) {
      index[name] = acc.length;
      acc.push({Name:name});      
    }
    
    // If this name doesn't have the color as a property
    // i.e. red or green, add it
    if (!acc[index[name]].hasOwnProperty(color)) {
      acc[index[name]][color] = 0;
    }
    
    // Increment the color value 
    ++acc[index[name]][color];
    return acc;
  }, []);
}

console.log(process0(input));

// Use template object so if object doesn't have color, value is 0
// Same algorithm as above.
function process1(data) {
  var index = Object.create(null);
  var temp = {red: 0, green: 0};

  return input.reduce(function (acc, obj) {
    var name = obj.Name;
  
    if (!index[name]) {
      index[name] = acc.length;
      acc.push(Object.assign({}, {Name:name}, temp));      
    }
    
    ++acc[index[name]][obj.color];
    return acc;
  }, []);
}

console.log(process1(input));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-12
    • 2022-08-13
    • 2018-07-17
    • 1970-01-01
    • 1970-01-01
    • 2017-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多