Removing empty object keys in an array of objects

2019-08-26 02:18发布

I'm trying to create an array that sort of summarises another array. I've already received some really good ideas here, all of them are working, but all of them generate another obstacle that I, again, can't seem to solve.

Based on @kooiinc's answer, my current code looks like this:

var grants = [
    { id: "p_1", location: "loc_1", type: "A", funds: "5000" },
    { id: "p_2", location: "loc_2", type: "B", funds: "2000" },
    { id: "p_3", location: "loc_3", type: "C", funds:  "500" },
    { id: "p_2", location: "_ibid", type: "D", funds: "1000" },
    { id: "p_2", location: "_ibid", type: "E", funds: "3000" }
];
var projects = [];
grants.map(
function (v) {
    if (!(v.id in this)) {
        this[v.id] = v;
        projects.push(v);
    } else {
        var current = this[v.id];
        current.type = [v.type].concat(current.type);
        current.funds = [v.funds].concat(current.funds);
    }
}, {});

... which gives the following desired result (type and funds joined into sub-arrays, the rest are pushed unchanged):

[
    { "id": "p_1", "location": "loc_1", "type": "A", "funds": "5000" },
    { "id": "p_2", "location": "loc_2", "type": ["E","D","B"], "funds": ["3000","1000","2000"] },
    { "id": "p_3", "location": "loc_3", "type": "C", "funds": "500" }
]

However, if some of the objects have some undefined key values, the result will have nulls in the arrays. For example like this (look at the type array):

[
    { "id": "p_1", "location": "loc_1", "type": "A", "funds": "5000" },
    { "id": "p_2", "location": "loc_2", "type": ["E",null,null], "funds": ["3000","1000","2000"] },
    { "id": "p_3", "location": "loc_3", "type": "C", "funds": "500" }
]

(Here's a fiddle with the same thing.)

I've tried to find a quick way of removing these afterwards (like here or here) but for some reason none of the usual methods (of recursively removing all keys that are undefined/null) seem to work, regardless of where I put them in my code. They don't give errors, they just won't remove anything.

Is it perhaps possible to already exclude the undefined keys in the mapping somehow?

Update: So some of the object keys won't have any values, just [null,null,null] whilst others will have a few but not all like ["E",null,null]. The idea is to remove all the null items and if there's nothing left then remove the object key as well.

2条回答
对你真心纯属浪费
2楼-- · 2019-08-26 02:45

I think you can test the occurrence of both type and funds properties and only if exist, then insert or update the element.

a.type && a.funds && ...

var grants = [
        { id: "p_1", location: "loc_1", type: "A", funds: "5000" },
        { id: "p_2", location: "loc_2", funds: "2000" },
        { id: "p_3", location: "loc_3", type: "C", funds: "500" },
        { id: "p_2", location: "_ibid", funds: "1000" },
        { id: "p_2", location: "_ibid", type: "E", funds: "3000" }
    ],
    project = [];

grants.forEach(function (a) {
    a.type && a.funds && !project.some(function (b, i) {
        if (a.id === b.id) {
            project[i].type.push(a.type);
            project[i].funds.push(a.funds);
            return true;
        }
    }) && project.push({ id: a.id, location: a.location, type: [a.type], funds: [a.funds] });
});
document.write('<pre>' + JSON.stringify(project, 0, 4) + '</pre>');

查看更多
叛逆
3楼-- · 2019-08-26 02:51

Try it this way:

grants.map(
 function (v) {
    if (!(v.id in this)) {
        // => initialize if empty
        v.type = v.type || [];
        v.funds = v.funds || [];
        this[v.id] = v;
        projects.push(v);
    } else {
        var current = this[v.id];
        current.type = v.type ? [v.type].concat(current.type) : current.type;
        current.funds = v.funds ? [v.funds].concat(current.funds) : current.funds;
    }
 }, {});

Now empty values will not show up in the result.

查看更多
登录 后发表回答