簡體   English   中英

如何對對象數組中的多個屬性值進行計數和分組?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM