0

I get a JSON object from PHP that holds multiple rows like this:

id | type   | amount| age
1  |  abc   |   1    |  1
2  |  def   |   2    |  1
3  |  def   |   4    |  2
4  |  def   |   13   |  3

I run it through JavaScript:

$.ajax({
    type: 'POST',
    url: "test.php",
    dataType: 'json',
    success: function (data) {
        var arr = [];
        for (var i = 0; i < data.length; i++) {
            arr[data[i].type][data[i].age] = data[i].ammount;
        }
    }
});

The idea is to get array that looks like this:

arr[def][1] = 2
arr[def][2] = 4
arr[def][3] = 13
arr[abc][1] = 1
arr[abc][2] = 0 // note that this one is just empty because it was not declared from json data.

Unfortunately I get an error:

Uncaught TypeError: Cannot set property '1' of undefined

1 is [data[i].age] and if I change its value error appears with other number.

Qantas 94 Heavy
  • 15,750
  • 31
  • 68
  • 83
Kalreg
  • 931
  • 3
  • 12
  • 31
  • what do you get and what do you end up with ? and why do you not use .push ? – Neta Meta Jan 12 '14 at 00:18
  • i get json object in which i can access all the properties ie data[i].type so i can get from data[3].type = def. i end up with error as described. i cant use push because all data i get is in random order - using proper keys i can easily sort it – Kalreg Jan 12 '14 at 00:21
  • I think you should initialize the inner array first. I suggest you to examine this question: http://stackoverflow.com/questions/13725138/javascript-multi-dimensional-dynamic-array. – kgd Jan 12 '14 at 00:22
  • well you cant create multiple D array without having the first array defined – Neta Meta Jan 12 '14 at 00:22

2 Answers2

5

You should do:

var arr = {};    
for (var i = 0; i < data.length; i++) {
   var type = data[i].type,
       age = data[i].age,
       amount = data[i].ammount;
   if(!arr[type]) arr[type] = {};  //Create arr[type] if it doesn't exist
   arr[type][age] = amount;
}

You could fill the empty cells with 0, but I'd better advise to do this for reading:

//returns the value or 0
function readArr(arr, type, age){
   if(!arr[type]) return 0;
   return arr[type][age] || 0;  
}

Then, instead of reading with arr["abc"][2], you'd read with readArr(arr, "abc", 2).

(If you prefer, of course you can avoid declaring a function but use its logic inline, you'd do something like (arr["abc"] ? arr["abc"][2] || 0 : 0) )

Cheers, from La Paz, Bolivia

Edgar Villegas Alvarado
  • 18,204
  • 2
  • 42
  • 61
  • this one works perfectly fine. thank you so much, also for some extra info. greetings from Olsztyn, Poland, Central Europe :) – Kalreg Jan 12 '14 at 00:30
  • Welcome, Kalreg, I work with a couple friends from Poland :), nice to have one more friend from there!. – Edgar Villegas Alvarado Jan 12 '14 at 00:32
  • "You could fill the empty cells with 0" - what empty cells, there are none? The thing you call `arr` is a javascript plain object, which is absolutely NOT an associative array. Javascript does not have associative arrays. – Beetroot-Beetroot Jan 12 '14 at 01:37
1

I think that's because arr['abc'] (or whatever the key is) is still undefined to be an array (or JSON object) when you set its abc property or key.

var arr = [];
for (var i = 0; i < data.length; i++) {
  if (!arr[data[i].type]) {
    arr[data[i].type] = [];
  }
  arr[data[i].type][data[i].age] = data[i].ammount;
}

Or if you want to use JSON objects

var arr = {};
for (var i = 0; i < data.length; i++) {
  if (!arr[data[i].type]) {
    arr[data[i].type] = {};
  }
  arr[data[i].type][data[i].age] = data[i].ammount;
}
Arnelle Balane
  • 5,437
  • 1
  • 26
  • 32