0

When I'm working with data, I normally have the need of create Arrays or Objects on a loop, let's say "on the fly".

Lets say for example I want to rearrange an array grouping the element by one of the array keys: One of the methods I use is to loop trough an for in. But the problem is when I define more than one index on the fly.

for(key in array){
   newArray[array[key]['gouping_key']] = array[key];
}

This example works fine. But if you have more than one element with the same grouping_key, this code is going to override your previous element.

So, I try this:

var i = 0;
for(key in array){
   newArray[array[key]['gouping_key']][i] = array[key];
   i++
}

But when I add that second index the interpreter complains saying that the newArray[array[key]['gouping_key']] is undefined. Problem it doesn´t seems to have on the previous example.

Why is that?

I've made this fiddle with an example in case the previous snippets an explanation would be insuficient and unclear. In the fiddle you have three snippets (two commented out).

The first one is the error I get when trying something like what Iǘe mentioned previously. The second is the solution I use. And the third an example of the creation of an array on the fly with only one index.

Summing up, I want to know why, when you add the second index, you get that error.

Thanks!

limoragni
  • 2,716
  • 2
  • 32
  • 50

2 Answers2

3
var i = 0;
for(key in array){

   // If nested object doesn't exist, make an empty one.
   newArray[array[key]['gouping_key']][i] =
     newArray[array[key]['gouping_key']][i] || [];

   newArray[array[key]['gouping_key']][i] = array[key];
   i++
}

You need to create an array to push to, it's not created for you. You can use the || operator to only create an empty array if it's undefined.

Also, that's a lot of nesting to follow... If I may...

var x, y;
y = 0;
for(key in array){
   x = array[key].gouping_key;
   newArray[x][y] = newArray[x][y] || []
   newArray[x][y] = array[key];
   y++
}

See how much more readable that is? It's also faster! You dont have to deeply traverse complex objects over and over again.

Alex Wayne
  • 178,991
  • 47
  • 309
  • 337
  • Perfect answer. The OR operator is much better than the IF I use in the fiddle. And of course, I need to keep learning how to get my code cleaner, your version is much more readable than mine. – limoragni Jan 21 '13 at 19:48
  • Ha, Sorry. I've spoke to soon. When I try the last snippet it still gives me cannot read property 0 of undefined. I'm trying this: http://jsfiddle.net/CmU2h/1/ – limoragni Jan 21 '13 at 20:03
0

First using for in for arrays is no good idea, it does not what you are expecting I think. see: https://stackoverflow.com/a/4261096/1924298. Using a simple for loop (or while) should solve your problem.

Community
  • 1
  • 1
Jens Peters
  • 2,075
  • 1
  • 22
  • 30