ES6 映射和减少频率计数
ES6 Mapping and reducing frequency count
我有一个 csv 文件,其中包含以下格式的数据(尽管数据更多)。
ID COL1 COL2 COL3 COL4
-----------------------------------------------------------
1 opt1 opt1 opt1 opt1
-----------------------------------------------------------
2 opt2 opt2 opt2 opt2
-----------------------------------------------------------
3 opt3 opt3 opt3 opt3
-----------------------------------------------------------
4 opt3 opt3 opt3 opt3
-----------------------------------------------------------
5 opt3 opt3 opt3 opt3
-----------------------------------------------------------
6 opt2 opt2 opt3 opt3
-----------------------------------------------------------
7 opt4 opt2 opt2 opt2
-----------------------------------------------------------
8 opt1 opt1 opt1 opt1
-----------------------------------------------------------
9 opt2 opt5 NA NA
-----------------------------------------------------------
我将这些数据传递到一个数组中。我想做的是只计算第一列中值的频率。所以目前,我定义了一个选项列表
let labels = ["opt1", "opt2", "opt3", "opt4"];
let data = [];
然后我有一个函数来计算按键
function countByKey (array, column, keyValue) {
let sum = 0;
for (let i = 0, len = array.length; i < len; i++) {
if (array[i][column] === keyValue) {
sum += 1;
}
}
return sum;
}
最后是输出频率的部分
for (let i in this.labels) {
data.push({
"Label": this.labels[i],
"Frequency": this.countByKey(this.csv, "COL1", this.labels[i])
});
}
这很好用,我最终得到了类似
的结果
[
{
Label: opt1
Frequency: 42
},
{
Label: opt2
Frequency: 108
},
...
]
但是,因为我现在在 VueJS 中使用 ES6,所以我发现有更简单的方法可以做到这一点。一种方法似乎是使用 Map 和 reduce。我试过这个
let acc = this.csv.reduce((acc, val) => acc.set(val, 1 + (acc.get(val) || 0)), new Map());
但这似乎输出了我的所有数据,并带有某种计数。如何使用 ES6 功能实现上述输出?
谢谢
第一步是使用reduce生成一个对象(或Map)来计算每个标签的频率。第二步是获取这个对象并将其转换为您想要的标签/频率对数组:
const csv = [
{ID: 1, COL1: 'opt1', COL2: 'opt1', COL3: 'opt1', COL4: 'opt1'},
{ID: 1, COL1: 'opt2', COL2: 'opt2', COL3: 'opt2', COL4: 'opt2'},
{ID: 1, COL1: 'opt3', COL2: 'opt3', COL3: 'opt3', COL4: 'opt3'},
{ID: 1, COL1: 'opt3', COL2: 'opt3', COL3: 'opt3', COL4: 'opt3'},
{ID: 1, COL1: 'opt3', COL2: 'opt3', COL3: 'opt3', COL4: 'opt3'},
{ID: 1, COL1: 'opt2', COL2: 'opt2', COL3: 'opt3', COL4: 'opt3'},
{ID: 1, COL1: 'opt4', COL2: 'opt2', COL3: 'opt2', COL4: 'opt2'},
{ID: 1, COL1: 'opt1', COL2: 'opt1', COL3: 'opt1', COL4: 'opt1'},
{ID: 1, COL1: 'opt2', COL2: 'opt5', COL3: 'NA', COL4: 'NA'}
]
const countByCol = col => {
const counts = csv.reduce((memo, row) => {
memo[row[col]] = (memo[row[col]] || 0) + 1;
return memo;
}, {});
return Object.entries(counts).map(([Label, Frequency]) => ({Label, Frequency}));
};
console.log(countByCol('COL1'))
我有一个 csv 文件,其中包含以下格式的数据(尽管数据更多)。
ID COL1 COL2 COL3 COL4
-----------------------------------------------------------
1 opt1 opt1 opt1 opt1
-----------------------------------------------------------
2 opt2 opt2 opt2 opt2
-----------------------------------------------------------
3 opt3 opt3 opt3 opt3
-----------------------------------------------------------
4 opt3 opt3 opt3 opt3
-----------------------------------------------------------
5 opt3 opt3 opt3 opt3
-----------------------------------------------------------
6 opt2 opt2 opt3 opt3
-----------------------------------------------------------
7 opt4 opt2 opt2 opt2
-----------------------------------------------------------
8 opt1 opt1 opt1 opt1
-----------------------------------------------------------
9 opt2 opt5 NA NA
-----------------------------------------------------------
我将这些数据传递到一个数组中。我想做的是只计算第一列中值的频率。所以目前,我定义了一个选项列表
let labels = ["opt1", "opt2", "opt3", "opt4"];
let data = [];
然后我有一个函数来计算按键
function countByKey (array, column, keyValue) {
let sum = 0;
for (let i = 0, len = array.length; i < len; i++) {
if (array[i][column] === keyValue) {
sum += 1;
}
}
return sum;
}
最后是输出频率的部分
for (let i in this.labels) {
data.push({
"Label": this.labels[i],
"Frequency": this.countByKey(this.csv, "COL1", this.labels[i])
});
}
这很好用,我最终得到了类似
的结果[
{
Label: opt1
Frequency: 42
},
{
Label: opt2
Frequency: 108
},
...
]
但是,因为我现在在 VueJS 中使用 ES6,所以我发现有更简单的方法可以做到这一点。一种方法似乎是使用 Map 和 reduce。我试过这个
let acc = this.csv.reduce((acc, val) => acc.set(val, 1 + (acc.get(val) || 0)), new Map());
但这似乎输出了我的所有数据,并带有某种计数。如何使用 ES6 功能实现上述输出?
谢谢
第一步是使用reduce生成一个对象(或Map)来计算每个标签的频率。第二步是获取这个对象并将其转换为您想要的标签/频率对数组:
const csv = [
{ID: 1, COL1: 'opt1', COL2: 'opt1', COL3: 'opt1', COL4: 'opt1'},
{ID: 1, COL1: 'opt2', COL2: 'opt2', COL3: 'opt2', COL4: 'opt2'},
{ID: 1, COL1: 'opt3', COL2: 'opt3', COL3: 'opt3', COL4: 'opt3'},
{ID: 1, COL1: 'opt3', COL2: 'opt3', COL3: 'opt3', COL4: 'opt3'},
{ID: 1, COL1: 'opt3', COL2: 'opt3', COL3: 'opt3', COL4: 'opt3'},
{ID: 1, COL1: 'opt2', COL2: 'opt2', COL3: 'opt3', COL4: 'opt3'},
{ID: 1, COL1: 'opt4', COL2: 'opt2', COL3: 'opt2', COL4: 'opt2'},
{ID: 1, COL1: 'opt1', COL2: 'opt1', COL3: 'opt1', COL4: 'opt1'},
{ID: 1, COL1: 'opt2', COL2: 'opt5', COL3: 'NA', COL4: 'NA'}
]
const countByCol = col => {
const counts = csv.reduce((memo, row) => {
memo[row[col]] = (memo[row[col]] || 0) + 1;
return memo;
}, {});
return Object.entries(counts).map(([Label, Frequency]) => ({Label, Frequency}));
};
console.log(countByCol('COL1'))