创建PHP多维关联数组的Javascript版本

I have a set of data that is not normalized. I do the normalization in PHP it it works just fine.

The dataset looks like this (screenshot bellow), it is a lot larger tho. I am only interested in orginizing the category and the type. With those two orginized I can make good tables and menu's.

Problem

Now the problem is, I am switching to an AJAX system, and the data no longer comes into PHP. Instead it comes directly into the page using node.js/mongodb. Is there a way I can do something like this:

<script type="text/javascript">

// Array containing all the objects from the server
// looks like this
var data = [Object, Object, Object];
var artikelen = [];

for(var i=0; i<data.length; i++){
  artikelen[data[i].categorie][data[i].type][] = data[i];
}

</script>

// ----------------
OLD SITUATION
//-----------------

In PHP I did this:

$sql = "SELECT *
        FROM mydb
        WHERE merk = 'webecos'
        ORDER BY categorie, type, code";

$result = $wpdb->get_results( $sql );

foreach($result as $row){
    $artikelen[$row->categorie][$row->type][] = $row;
}

Now I can make good sorted tables / menu with nested loops. The code I used is this.

<ul id="inkoop_menu">
    <?php foreach ( $artikelen as $categorie => $row ): ?>
    <li>
        <a class="inkoop_button" data-menu="categorie" href="#">
            <?=$categorie; ?>
        </a>
        <ul>
            <?php foreach ( $row as $type => $artikel ): ?>
            <li>
                <a class="inkoop_button" data-menu="type" href="#">
                    <?=$type; ?>
                </a>
            </li>
            <?php endforeach; ?>
        </ul>
    </li>
    <?php endforeach; ?>
</ul>

Edit

Maybe this is a but better to understand. The array I am after looks like this:

array['categorie-name']['type-name'][x] = whole object;

enter image description here

I'm not really sure I totally follow you, but do you mean something like this?

var data = [Object, Object, Object];
var artikelen = [];

for(var i=0; i<data.length; i++){

    if( !artikelen[data[i].category])
        artikelen[data[i].category] = new Array();

    if( !artikelen[data[i].category][data[i].type] )
        artikelen[data[i].category][data[i].type] = new Array();

    artikelen[data[i].category][data[i].type].push(data[i]);
}

More complete example: (also note I put category instead of categorie, change if needed).

<script language="javascript" type="text/javascript">

var obj1 = new Object();
obj1.category = 1;
obj1.type = 2;
obj1.id = 1;

var obj2 = new Object();
obj2.category = 1;
obj2.type = 2;
obj2.id = 2;

var obj3 = new Object();
obj3.category = 2;
obj3.type = 4;
obj3.id = 3;


// Array containing all the objects from the server
// looks like this
var data = [obj1, obj2, obj3];
var artikelen = [];

for(var i=0; i<data.length; i++){

    if( !artikelen[data[i].category])
        artikelen[data[i].category] = new Array();

    if( !artikelen[data[i].category][data[i].type] )
        artikelen[data[i].category][data[i].type] = new Array();

    artikelen[data[i].category][data[i].type].push(data[i]);
}

alert( artikelen[1][2] ); // expected [object], [object]

alert( artikelen[1][2][0].type ); // expected 2

</script>

Key things to take away from this approach:

  • Check if array at key exists
  • If not, create it
  • .push can be used on a javascript array to add an item to an array

Using a string as a type for an object:

var obj1 = new Object();
obj1.category = 1;
obj1.type = "hello hello";
obj1.id = 1;

var obj2 = new Object();
obj2.category = 1;
obj2.type = 2;
obj2.id = 2;

var obj3 = new Object();
obj3.category = 2;
obj3.type = 4;
obj3.id = 3;


// Array containing all the objects from the server
// looks like this
var data = [obj1, obj2, obj3];
var artikelen = [];

for(var i=0; i<data.length; i++){

    if( !artikelen[data[i].category])
        artikelen[data[i].category] = new Array();

    if( !artikelen[data[i].category][data[i].type] )
        artikelen[data[i].category][data[i].type] = new Array();

    artikelen[data[i].category][data[i].type].push(data[i]);
}

alert( artikelen[1][2] ); // expected [object], [object]

alert( artikelen[1]["hello hello"][0].type ); // expected "hello hello"

EDIT

I gave it some more, thought and after reading this, it turns out that arrays in Javascript are not well suited to be used as associative arrays (like in PHP). In actuality, you are just adding attributes to an object. So making it an object instead is better. For example, the following:

var obj1 = new Object();
obj1.category = 1;
obj1.type = "hello hello";
obj1.id = 1;

var obj2 = new Object();
obj2.category = 1;
obj2.type = 2;
obj2.id = 2;

var obj3 = new Object();
obj3.category = 2;
obj3.type = 4;
obj3.id = 3;


// Array containing all the objects from the server
// looks like this
var data = [obj1, obj2, obj3];
var artikelen = [];

for(var i=0; i<data.length; i++){

    if( !artikelen[data[i].category])
        artikelen[data[i].category] = new Object();

    if( !artikelen[data[i].category][data[i].type] )
        artikelen[data[i].category][data[i].type] = new Object();

    artikelen[data[i].category][data[i].type] = (data[i]);
}

console.dir( artikelen ); // if using a debugger with console, gives detailed info

Also, if using a debugger, such as Firebug in Firefox, you can see detailed info with the console.dir function.

Are you still able to work with PHP? If so, you can always bring the data from the server in the JSON format and let the client (in your case, the javascript language) read it and interpret it.