0

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 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Yep, I thought of this too but this doesn't seem to remove all the nulls, see here: jsfiddle.net/eebgasw6/1
I see, there is a pretty simple solution. See edited answer
0

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

1 Comment

The problem with this would be that I lose the ability to join the ones I want to join (type and funds in the example).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.