在javascript

时间:2018-01-17 00:34:10

标签: javascript arrays ecmascript-6 lodash

我最终用了繁琐的循环来转换

[{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},
]

红色和绿色只有2种颜色,所以也可以硬编码。

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

2 个答案:

答案 0 :(得分:2)



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))




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

答案 1 :(得分:0)

另一种方法是使用reduce。如果基于固定属性名称红色绿色使用模板对象,则代码可能会更短。

以下两种解决方案都使用索引对象来跟踪命名对象在结果数组中的位置,类似于pattpass'使用地图。如果特定名称具有该颜色,则第一解决方案仅在解决方案中包括颜色。第二个解决方案使用具有固定属性的模板对象,因此如果对象没有颜色,则结果中的值为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));