0

I have js array as seen below:

var names = [{name:"high",id:1},{name:"high",id:2}, 
{name:"low",id:1},  {name:"low",id:2},{name:"medium",id:1},{name:"medium",id:2}];

I need to create another array out of this like this.

var newArr=[{name:high,items:[1,2]},{name:low,items:[1,2]},{name:medium,items:[1,2]}];

Please suggest me how to do that.

0

4 Answers 4

2

Underscorejs based solution

var obj = {};

_.each(names, function (e) {
    var o = obj[e.name];
    if (o) {
        o.items.push(e.id);
    } else {
        o = {name: e.name, items: [e.id]};
    }
    obj[e.name] = o;
});

var result = _.map(obj, function (e) {return e;});

Pure js

var obj = {};
for (var i = 0; i < names.length; i++) {
    var e = names[i];
    var o = obj[e.name];
    if (o) {
        o.items.push(e.id);
    } else {
        o = {name: e.name, items: [e.id]};
    }
    obj[e.name] = o;
}
var result = [];
for (var k in obj) {
    if (obj.hasOwnProperty(k)) {
        result.push(obj[k]);
    }
};
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks.. I have used the pure js one and it is working perfectly at my end. Thanks
1

Here is a simple to understand solution without external library.

var newArr = []
for ( var i in names ) {
    var exists = findItemInArray(names[i].name,newArr);
    if(exists) {                // Another item with same name was added to newArray
       var items = exists.items.push(names[i].id);    // We add the id to existing item
    } else {                   // No other item with same name was added to newArray
       var newItem = {name:names[i].name, items:names[i].id};
       newArr.push(newItem);
    }
}

And I made this function to return the item if it already exists in newArray

function findItemInArray(name,array){
    for(var i in array){
       if(array[i].name === name){
           return array[i];
       }
    return null;
}

Comments

1

Here's a solution that uses no external libraries:

/**
 * Add the given object to the given set.
 *
 * @param {object} theSet The set to add this object to.
 * @param {object} theObject The object to add to the set.
 *
 * @return {object} theSet, with theObject added to it.
 *
 * @note Assumes that theObject.name should be the key,
 *       while theObject.id should go into the value array.
 * @note This is an Array.prototype.reduce() callback.
 */
function collect(theSet, theObject) {
    if (theSet.hasOwnProperty(theObject.name)) {
        theSet[theObject.name].push(theObject.id);
    } else {
        theSet[theObject.name] = [theObject.id];
    }
    return theSet;
}
var names = [{name:"high",id:5},{name:"high",id:6}, 
             {name:"low",id:1},  {name:"low",id:2},{name:"medium",id:3},{name:"medium",id:4}],
    combinedSet = names.reduce(collect, {}), // This is Step 1
    final = [],
    key;

// This is Step 2
for (key in combinedSet) {
    if (combinedSet.hasOwnProperty(key)) {
        final.push(
            {
                "name" : key,
                "items": combinedSet[key]
            }
        );
    }
}

The first step is to group the IDs under the object names. I use Array.prototype.reduce to do this, with the callback collect. The result of that transformation goes into the combinedSet variable.

The second step is to take the set we made in Step 1 and turn it into the final array: make objects using the set's keys as the name member, and use its values as the items member. I can't use reduce like I could before, so I go with a simple for loop. Note that I wrapped things up with a hasOwnProperty check, to guard against the possibility that someone has modified Object.prototype; if I didn't do this, then there might be more items in the set that I hadn't put there, and that would introduce bugs.

Comments

0

You are looking for a grouping function. Try underscoreJs groupBy:

jsFiddle

var names = [{name:"high",id:1},{name:"high",id:2}, {name:"low",id:1},  {name:"low",id:2},{name:"medium",id:1},{name:"medium",id:2}];

console.debug(_.groupBy(names, 'name'));
// Object {high: Array[2], low: Array[2], medium: Array[2]}, where each item in the nested arrays refers to the original object

Comments

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.