Sign up ×
Stack Overflow is a community of 4.7 million programmers, just like you, helping each other. Join them; it only takes a minute:

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.

share|improve this question
up vote 1 down vote accepted

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.

share|improve this answer
    
Yep, I thought of this too but this doesn't seem to remove all the nulls, see here: jsfiddle.net/eebgasw6/1 – tmr Sep 27 '15 at 10:51
    
I see, there is a pretty simple solution. See edited answer – KooiInc Sep 27 '15 at 11:38

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

share|improve this answer
    
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). – tmr Sep 27 '15 at 13:46

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.