将 JSON 数组缩减为具有组合键值的对象

Reduce JSON array to object with combined key-values

我有一个这样的数组:

[
    { "avl_res": 1, "res_status": "Available", "code": "AAA" },
    { "avl_res": 2, "res_status": "Unavailable", "code": "AAA" },
    { "avl_res": 2, "res_status": "Available", "code": "BBB" },
    { "avl_res": 1, "res_status": "Available", "code": "CCC" },
    { "avl_res": 5, "res_status": "Unavailable", "code": "CCC" },
    { "avl_res": 3, "res_status": "Unavailable", "code": "DDD" },
];

我正在尝试制作这个:

[
    {"avl_res":1,"total_res":3,"code":"AAA"},
    {"avl_res":2,"total_res":2,"code":"BBB"},
    {"avl_res":1,"total_res":6,"code":"CCC"},
    {"avl_res":0,"total_res":3,"code":"DDD"},
];

根据这个 question 的答案,我设法做到了:

var singles = {};
arr.forEach(function (item) {
    var single = singles[item.code] = singles[item.code] || {};
    single[item.res_status] = item.avl_res;
});

var outputList = [];
for (var single in singles) {
    let total_res = 0;
    let avl_res = 0;

    singles[single]['Available'] ? avl_res = singles[single]['Available'] : avl_res = 0;
    singles[single]['Unavailable'] ? total_res = avl_res + singles[single]['Unavailable'] : total_res = avl_res;

    outputList.push({ code: single, total_res: total_res, avl_res: avl_res });
}

console.log(outputList);

只是想知道这是否足够有效,或者是否有 better/elegant 方法,也许可以使用其他 JS 函数(例如 reduce、map 等)。干杯!

如果你那么关心代码性能(效率),你会喜欢这个...

const arr = [
    { "avl_res": 1, "res_status": "Available", "code": "AAA" },
    { "avl_res": 2, "res_status": "Unavailable", "code": "AAA" },
    { "avl_res": 2, "res_status": "Available", "code": "BBB" },
    { "avl_res": 1, "res_status": "Available", "code": "CCC" },
    { "avl_res": 5, "res_status": "Unavailable", "code": "CCC" },
    { "avl_res": 3, "res_status": "Unavailable", "code": "DDD" },
];

const results = [];
const findItem = {};

for (const { avl_res, code, res_status } of arr) {
    let item = findItem[code];
    const res = res_status == 'Available' ? avl_res : 0;
    if (item) {
        item.total_res += avl_res;
        item.avl_res += res;
    }
    else {
        item = { avl_res: res, total_res: avl_res, code };
        results.push(item);
        findItem[code] = item;
    }
}
console.log(results);