11

I have an array that is created dynamic from an xml document looking something like this:

myArray[0] = [1,The Melting Pot,A]
myArray[1] = [5,Mama's MexicanKitchen,C]
myArray[2] = [6,Wingdome,D]
myArray[3] = [7,Piroshky Piroshky,D]
myArray[4] = [4,Crab Pot,F]
myArray[5] = [2,Ipanema Grill,G]
myArray[6] = [0,Pan Africa Market,Z]

This array is created within a for loop and could contain whatever based on the xml document

What I need to accomplish is grouping the items from this array based on the letters so that all array objects that have the letter A in them get stored in another array as this

other['A'] = ['item 1', 'item 2', 'item 3'];
other['B'] = ['item 4', 'item 5'];
other['C'] = ['item 6'];

To clarify I need to sort out items based on variables from within the array, in this case the letters so that all array objects containing the letter A goes under the new array by letter

Thanks for any help!

Tobias
  • 494
  • 3
  • 14
  • 30

6 Answers6

10

You shouldn't use arrays with non-integer indexes. Your other variable should be a plain object rather than an array. (It does work with arrays, but it's not the best option.)

// assume myArray is already declared and populated as per the question

var other = {},
    letter,
    i;

for (i=0; i < myArray.length; i++) {
   letter = myArray[i][2];
   // if other doesn't already have a property for the current letter
   // create it and assign it to a new empty array
   if (!(letter in other))
      other[letter] = [];

   other[letter].push(myArray[i]);
}

Given an item in myArray [1,"The Melting Pot","A"], your example doesn't make it clear whether you want to store that whole thing in other or just the string field in the second array position - your example output only has strings but they don't match your strings in myArray. My code originally stored just the string part by saying other[letter].push(myArray[i][1]);, but some anonymous person has edited my post to change it to other[letter].push(myArray[i]); which stores all of [1,"The Melting Pot","A"]. Up to you to figure out what you want to do there, I've given you the basic code you need.

nnnnnn
  • 147,572
  • 30
  • 200
  • 241
  • I edited your answer, to account for a missing parentheses and adding the whole array to the object, not only the title. Here is your [demo](http://jsfiddle.net/Shef/7Nnqt/). I hope you don't mind. :) – Shef Sep 29 '11 at 12:00
  • 2
    @nnnnnn _"some anonymous person has edited my post"_ LOL. I left a comment, apart from SO's automatic logging of editing history, does't look like much of an anonymity to me. :D – Shef Sep 29 '11 at 12:11
  • @Shef - Sorry, yes, I see your comment (both your comments) now, but at the time I wrote that SO was refusing to show me the edit history and I thought it must be because you'd made the edit in the initial grace period when a history isn't kept. Ironically when your change went through I was in the midst of editing it myself specifically to point out that I had stored just the title part and to ask what the actual requirement was. SO popped up a warning about your edit but wouldn't tell me the details for some reason. – nnnnnn Sep 29 '11 at 12:17
  • P.S. Thanks for the demo @Shef. – nnnnnn Sep 29 '11 at 12:20
6

Try groupBy function offered by http://underscorejs.org/#groupBy

_.groupBy([1.3, 2.1, 2.4], function(num){ return Math.floor(num); });

Result => {1: [1.3], 2: [2.1, 2.4]}
slv007
  • 328
  • 4
  • 10
2

You have to create an empty JavaScript object and assign an array to it for each letter.

var object = {};

for ( var x = 0; x < myArray.length; x++ )
{
    var letter = myArray[x][2];

    // create array for this letter if it doesn't exist
    if ( ! object[letter] )
    {
        object[letter] = [];
    }

    object[ myArray[x][2] ].push[ myArray[x] ];
}

Demo fiddle here.

Jose Faeti
  • 12,126
  • 5
  • 38
  • 52
1

This code will work for your example.

var other = Object.create(null),  // you can safely use in opeator.
    letter,
    item,
    max,
    i;

for (i = 0, max = myArray.length; i < max; i += 1) {
   item = myArray[i];
   letter = myArray[2];

   // If the letter does not exist in the other dict,
   // create its items list
   other[letter] = other[letter] || [];
   other.push(item);
}
user278064
  • 9,982
  • 1
  • 33
  • 46
1

Good ol' ES5 Array Extras are great.

var other = {};
myArray.forEach(function(n, i, ary){
    other[n[2]] = n.slice(0,2);
});
kzh
  • 19,810
  • 13
  • 73
  • 97
0

Try -

var myArray = new Array();
myArray[0] = [1,"The Melting Pot,A,3,Sake House","B"];
myArray[1] = [5,"Mama's MexicanKitchen","C"];
myArray[2] = [6,"Wingdome","D"];
myArray[3] = [7,"Piroshky Piroshky","D"];
myArray[4] = [4,"Crab Pot","F"];
myArray[5] = [2,"Ipanema Grill","G"];
myArray[6] = [0,"Pan Africa Market","Z"];

var map = new Object();
for(i =0 ; i < myArray.length; i++){
    var key = myArray[i][2];
    if(!map[key]){
       var array = new Array();        
        map[key] = array;
    }
    map[key].push(myArray[i]);

}
Jayendra
  • 52,349
  • 4
  • 80
  • 90