1

I have an array:

["car1-coupe", "car2-convertible", "car2-hatchback", "car2-estate", "car3-hatchback", "car3-estate"] 

The array can have different sets of cars, and I want to turn it into something like this:

[{
    car1: ["car1-coupe"]
},{
    car2: ["car2-convertible", "car2-hatchback", "car2-estate"]
},{
    car3: ["car3-hatchback", "car3-estate"]
}]

How can I do this in JavaScript or Underscore?

5
  • Do you absolutely need that output? Or can it be slightly different? Commented Oct 24, 2014 at 14:01
  • By looping yourself or using map() which will loop internally Commented Oct 24, 2014 at 14:01
  • 1
    You want to turn it into "something like" that or you want to turn it into precisely that? I don't know why you'd store it that way, personally; seems like it would make more sense to have a single object (abandoning the wrapping array) with three properties: car1, car2 and car3. Commented Oct 24, 2014 at 14:02
  • What exactly are you having problems with? Iterating over the array? Splitting a string? Adding properties to an object? You matt have tried something and got stuck somewhere... what is it? Commented Oct 24, 2014 at 14:02
  • @Cerbrus the output can be different as long as I have the models grouped by cars. Felix My problem is about the grouping Commented Oct 24, 2014 at 14:06

3 Answers 3

2

So, assuming an array like this:

var a = ["car1-coupe", "car2-convertible", "car2-hatchback", "car2-estate", "car3-hatchback", "car3-estate"];

You can do this:

var b = a.reduce(function(prev, curr){
    var car = curr.split('-')[0]; // "get" the current car
    prev[car] = prev[car] || [];  // Initialize the array for the current car, if necessary.
    prev[car].push(curr);         // Add the current item to the array.
    return prev;
}, {});

This will return the following object:

{
    car1: ["car1-coupe"],
    car2: ["car2-convertible", "car2-hatchback", "car2-estate"],
    car3: ["car3-hatchback", "car3-estate"]
}
Sign up to request clarification or add additional context in comments.

5 Comments

thanks, unfortunately needs to work in IE8, reduce() is works in IE9 onwards, sorry forgot to mention it.
@Mauro74 you can easily add a shim.
No worries, you can find a polyfill for reduce() on the MDN site.
Ok @Cerbrus I'll use the Polyfill!
With the polyfill in place, does this answer (and it's output) work for you?
0

var array = ["car1-coupe", "car2-convertible", "car2-hatchback", "car2-estate", "car3-hatchback", "car3-estate"];

var result = {};

for (var i = 0; i < array.length; i++) {
  var key = array[i].split('-')[0]; // The car we're interested in
  if (result[key]) { // Check if this car has already been initialized
    result[key].push(array[i]); //add this model to the list
  } else {
    result[key] = [array[i]]; // initialize the array with the first value
  }
}

console.log(result);
/*will return :
{
  car1: ["car1-coupe"],
  car2: ["car2-convertible", "car2-hatchback", "car2-estate"],
  car3: ["car3-hatchback", "car3-estate"]
}
*/

Comments

-1
var  myObj = {}, myArr = [];
for( var i = 0; i < arr.length; i+=1) {
      var key = arr[i].split("-")[0];
      myObj = {};
      myObj[key] = [];
      for( var j = i; j < arr.length; j+=1 ) {
            if( key === arr[j].split("-")[0])
                myObj[key].push(arr[j]);
      }
      myArr.push(myObj);
}

I think this can be done simply with this way. One loop to get the key and another inner loop to get all values of this key.

1 Comment

Waaaaaaay too many temporary variables, 2 loops, and no explanation at all. -1

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.