1

I have an array like this:

[
    { "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" },
];

I am trying to produce this:

[
    {"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"},
];

Following the answer to this question, I managed to do it with this:

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);

Just wondering if this is efficient enough or there's a better/elegant way, maybe by using other JS functions (e.g. reduce, map, etc.). Cheers!

Nur
  • 2,361
  • 2
  • 16
  • 34

1 Answers1

1

If you care code performance (efficiency) that much, You would like this...

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);
Nur
  • 2,361
  • 2
  • 16
  • 34
  • Why not use a plain `find` object instead of adding that as a property to array? – adiga Apr 26 '21 at 07:59
  • There is no problem to use find() But In this case, I just want to write super efficiency code, Even we should trust efficiency about build in function in JavaScript, Although find() is not just loop, it use function as loop, and function call is expensive... – Nur Apr 26 '21 at 08:32
  • I didn't mean `array.find` method. I meant why not use a `const find = {}` object directly instead of adding that property to the array like `results.find` . Arrays shouldn't be assigned anything other than an integer property – adiga Apr 26 '21 at 08:38
  • Although in my case, Its fine to do, But for your (@adiga) sake, I edited my answer... – Nur Apr 26 '21 at 08:48