[英]How to count multiple properties values in array of objects using lodash?
[英]How to count and group multiple properties values in array of objects?
我有一個對象數組:
[
{'year': 2019, 'a_academic': 3, 'f_security': 4, ..., 'k_services': 3},
{'year': 2019, 'a_academic': 2, 'f_security': 2, ..., 'k_services': 4},
{'year': 2019, 'a_academic': 3, 'f_security': 3, ..., 'k_services': 1},
...
{'year': 2019, 'a_academic': 3, 'f_security': 3, ..., 'k_services': 3},
]
如何計算多個屬性值,然后將其分組,並將其保存在一個新對象中,例如:
{
'a_academic': {
4: 0,
3: 3,
2: 1,
1: 0
},
'f_security': {
4: 1,
3: 2,
2: 1,
1: 0
},
...,
'k_services': {
4: 1,
3: 2,
2: 0,
1: 1
}
}
我可以使用 reduce 和手動訪問密鑰來做到這一點,但僅限於一個屬性:
let count = array.reduce((res, cur) => {
res[cur.a_academic] = res[cur.a_academic] ? res[cur.a_academic] + 1 : 1;
return res;
}, {});
console.log(count);
結果:
{
3: 3,
2: 1
}
如何有效地實現這一點,使其適用於所有其他屬性,而無需手動訪問它?
您可以定義一個要計算的鍵數組,然后在Object.entries
上使用帶有嵌套forEach
循環的reduce
方法,並計算每個已定義鍵的出現值。
const data = [ {'year': 2019, 'a_academic': 3, 'f_security': 4, 'k_services': 3}, {'year': 2019, 'a_academic': 2, 'f_security': 2, 'k_services': 4}, {'year': 2019, 'a_academic': 3, 'f_security': 3, 'k_services': 1}, {'year': 2019, 'a_academic': 3, 'f_security': 3, 'k_services': 3}, ] const props = ['a_academic', 'f_security', 'k_services'] const result = data.reduce((r, e) => { Object.entries(e).forEach(([k, v]) => { if (props.includes(k)) { if (!r[k]) r[k] = {} r[k][v] = (r[k][v] || 0) + 1 } }) return r; }, {}) console.log(result)
要在每個對象中填充空值,您必須首先找到整個數據的最小值和最大值,而且還必須僅找到定義的道具。
const data = [ {'year': 2019, 'a_academic': 3, 'f_security': 4, 'k_services': 3}, {'year': 2019, 'a_academic': 2, 'f_security': 2, 'k_services': 4}, {'year': 2019, 'a_academic': 3, 'f_security': 3, 'k_services': 1}, {'year': 2019, 'a_academic': 3, 'f_security': 3, 'k_services': 3}, ] const props = ['a_academic', 'f_security', 'k_services'] const values = data.map(e => { return Object.entries(e) .filter(([k]) => props.includes(k)) .map(([k, v]) => v) }).flat() const max = Math.max(...values) const min = Math.min(...values) const result = data.reduce((r, e) => { Object.entries(e).forEach(([k, v]) => { if (props.includes(k)) { if (!r[k]) { r[k] = {} for (let i = min; i <= max; i++) { r[k][i] = 0 } } r[k][v] += 1 } }) return r; }, {}) console.log(result)
您需要通過從對象中省略year
來進行嵌套分組。
var data = [{ year: 2019, a_academic: 3, f_security: 4, k_services: 3 }, { year: 2019, a_academic: 2, f_security: 2, k_services: 4 }, { year: 2019, a_academic: 3, f_security: 3, k_services: 1 }, { year: 2019, a_academic: 3, f_security: 3, k_services: 3 }], grouped = data.reduce((r, { year, ...o }) => { Object.entries(o).forEach(([k, v]) => { r[k] = r[k] || {}; r[k][v] = (r[k][v] || 0) + 1; }); return r; }, {}); console.log(grouped);
你所做的是使用cur.academic
的值而不是鍵名。 為了更好地解釋這一點,請考慮這個
const obj = { alpha: 20, beta: 30, gamma: 40 };
console.log(obj['alpha']); // outputs 20
你可以做的是:
const array = [
{'year': 2019, 'a_academic': 3, 'f_security': 4, 'k_services': 3},
{'year': 2019, 'a_academic': 2, 'f_security': 2, 'k_services': 4},
{'year': 2019, 'a_academic': 3, 'f_security': 3, 'k_services': 1},
{'year': 2019, 'a_academic': 3, 'f_security': 3, 'k_services': 3},
];
const excludedKeys = ['year'];
let count = array.reduce((res, curr) => {
// Select the keys you are going to use and exclude the ones you won't
const keys = Object.keys(curr).filter(key => !excludedKeys.includes(key));
keys.forEach(key => {
res[key] = res[key] ? res[key] + 1 : 1;
});
return res;
}, {});
console.log(count);
您可以從一個對象(不包括year
)中獲取鍵,然后將每個鍵映射到一個計數數組。 例如, a_academic
的值數組[3, 2, 3, 3]
映射到[0, 0, 1, 3, 0]
。 使用這個total
組,您可以使用Object.assign()
將其索引分配給一個對象,您可以將其用於每個組,如下所示:
const arr = [ {'year': 2019, 'a_academic': 3, 'f_security': 4, 'k_services': 3}, {'year': 2019, 'a_academic': 2, 'f_security': 2, 'k_services': 4}, {'year': 2019, 'a_academic': 3, 'f_security': 3, 'k_services': 1}, {'year': 2019, 'a_academic': 3, 'f_security': 3, 'k_services': 3}, ]; const groupArr = ([{year, ...first}, ...arr]) => { const ent = Object.entries(first); const gr = ent.map(([key, v]) => [v, ...arr.map(o => o[key])]); const maxN = Math.max(...gr.flat()); const minN = Math.min(...gr.flat()); const total = gr.map(arr => arr.reduce((tally, n) => (tally[n]++, tally), Array(minN).concat(Array(maxN).fill(0))) ); return Object.assign({}, ...ent.map(([k], i) => ({[k]: Object.assign({}, total[i])}))); } console.log(groupArr(arr));
只需為您的邏輯添加Object.keys
循環即可動態訪問密鑰。
const array = [ { year: 2019, a_academic: 3, f_security: 4, k_services: 3 }, { year: 2019, a_academic: 2, f_security: 2, k_services: 4 }, { year: 2019, a_academic: 3, f_security: 3, k_services: 1 }, { year: 2019, a_academic: 3, f_security: 3, k_services: 3 } ]; let count = array.reduce((res, cur) => { Object.keys(cur) .filter(key => key.includes("_")) .forEach(key => { const obj = res[key] || {}; res[key] = { ...obj, [cur[key]]: (obj[cur[key]] || 0) + 1 }; }); return res; }, {}); console.log(count);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.