2016-08-01 99 views
0

对象数组我想用减少方法和映射得到这个结果如下:使用地图和减少让我在的</p> <pre><code>var c = [{name: 'John'}, {name: 'John'}, {name: 'Tom'}]; </code></pre> <p>数组

result = [ 
    { name: "John", occurence: 2 }, 
    { name: "Tom", occurence: 1 } 
    ] 

这里是一个尝试我已经尝试,但仍然没有完全得到它。 https://jsfiddle.net/joeSaad/up3ddfzz/

c = [{ 
 
    name: 'John' 
 
}, { 
 
    name: 'John' 
 
}, { 
 
    name: 'Simon' 
 
}]; 
 

 
var d = c.reduce((countMap, word) => { 
 
    countMap[word.name] = ++countMap[word.name] || 1; 
 
    return countMap 
 
}, []); 
 

 
var e = c.reduce((countMap, word) => { 
 
    q = []; 
 
    countMap[word.name] = ++countMap[word.name] || 1; 
 
    var p = { 
 
    name: word.name, 
 
    occurence: countMap[word.name] 
 
    } 
 
    q.push(p); 
 
    return q 
 
}, []); 
 

 
console.log(e);

帮助非常感谢。在此先感谢

+1

你忘了张贴的尝试? – Li357

+0

@AndrewL。谢谢!只是编辑了问题 –

+0

@ mike-c似乎现在在我的jsfiddle中运行不起作用.. –

回答

3

你是绝对正确的轨道减少工作,但我的计算分成两个不同的步骤

let c = [{name: 'John'}, {name: 'John'}, {name: 'Tom'}]; 
 

 
const pairs = o=> Object.keys(o).map(k=> [k, o[k]]) 
 

 
let count = c.reduce((acc, {name}) => { 
 
    if (acc[name] === undefined) 
 
    return Object.assign(acc, { [name]: 1 }) 
 
    else 
 
    return Object.assign(acc, { [name]: acc[name] + 1 }) 
 
}, {}) 
 

 
var result = pairs(count).map(([name, occurences]) => ({name, occurences})) 
 

 
console.log(result) 
 
//=> [ { name: 'John', occurences: 2 }, { name: 'Tom', occurences: 1 } ]


你可以抽象这些行为进入不同的功能,像这样

// convert an object to [[key,value]] pairs 
 
const pairs = o=> Object.keys(o).map(k=> [k, o[k]]) 
 

 
// count unique instances of a property value in an array of objects 
 
const countBy = (prop, xs)=> { 
 
    return xs.reduce((acc, x)=> { 
 
    let y = x[prop] 
 
    if (acc[y] === undefined) 
 
     return Object.assign(acc, { [y]: 1 }) 
 
    else 
 
     return Object.assign(acc, { [y]: acc[y] + 1 }) 
 
    }, {}) 
 
} 
 

 
// your data 
 
let c = [{name: 'John'}, {name: 'John'}, {name: 'Tom'}] 
 

 
// then chain it all together 
 
let result = pairs(countBy('name', c)).map(([name, occurences]) => ({name, occurences})) 
 

 
console.log(result) 
 
//=> [ { name: 'John', occurences: 2 }, { name: 'Tom', occurences: 1 } ]


ES6还提供Map这是做这种计算的相当不错。

这段代码对我来说有点更好,而且语义上更正确一点。我们以前的代码做的是完全相同的事情,只是它使用了一个普通的对象。 Map是专门为此key->value数据设计的数据结构,因此使Map成为更好的选择。

唯一的问题是,如果你的代码库还没有以某种方式使用Google Maps,那么仅仅为此引入它们可能是错误的举动。

// convert a Map to an array of pairs 
 
const mpairs = m=> [...m.entries()] 
 

 
// countBy this time uses Map 
 
const countBy = (prop, xs)=> { 
 
    return xs.reduce((m, x)=> { 
 
    let y = x[prop] 
 
    if (m.has(y)) 
 
     return m.set(y, m.get(y) + 1) 
 
    else 
 
     return m.set(y, 1) 
 
    }, new Map) 
 
} 
 

 
// your data 
 
let c = [{name: 'John'}, {name: 'John'}, {name: 'Tom'}] 
 

 
// then chain it all together 
 
let result = mpairs(countBy('name', c)).map(([name, occurences]) => ({name, occurences})) 
 

 
console.log(result) 
 
//=> [ { name: 'John', occurences: 2 }, { name: 'Tom', occurences: 1 } ]

+0

这绝对有效。感谢@naomik我仍然试图理解为什么我们有const对。我们没有使用它。另外我不安静得到第二种方法。再次感谢! –

+0

我们绝对使用它'双';仔细阅读代码。第二部分的意思是建议你将这些东西包装在一个函数中,这样它就不会混淆其余的代码。我在那里添加了一些注释,并且还添加了第三部分,它显示了如何使用更多语义数据结构来执行相同的计算。 – naomik

相关问题