Convert JSON to multidimensional JavaScript array - php

I receive from the server a JSON like the following:
{"0":{"0":"image1.jpg","1":"texthere","2":"0"},"1":{"0":"image66.jpg","1":"texthere","2":"1"},"2":{"0":"image12.jpg","1":"texthere","2":"2"},"3":{"0":"image44.jpg","1":"texthere","2":"3"},"4":{"0":"image34.jpg","1":"texthere","2":"4"},"5":{"0":"image33.jpg","1":"texthere","2":"5"},"6":{"0":"image21.jpg","1":"texthere","2":"6"},"7":{"0":"image32.jpg","1":"texthere","2":"7"},"8":{"0":"image13.jpg","1":"texthere","2":"8"},"9":{"0":"image11.jpg","1":"texthere","2":"9"},"10":{"0":"image03.jpg","1":"texthere","2":"10"},"length":"12"}
The developer who coded this used JSON_FORCE_OBJECT as a parameter of the json_encode method in PHP.
In JavaScript is there any "magics" (that is, not a custom function) to convert this structure to a multidimensional array?
I would want something like:
[["image1.jpg","texthere","2"],["image66.jpg","texthere","1"]]...
Disclaimers:
- I'm looking for a native implementation (not JQuery);
- The PHP can be eventually changed (if needed);
Any help is appreciated, thanks in advance.

The easiest way I can think of to do what you want is to use regular expressions to convert the JSON from object literals to array literals.
Unfortunately, Simon Cowell is more magical than this approach.
//I don't know why you don't want a custom function.
function dataToArray(data)
{
data = data.replace(/"[0-9]+":/g,""); //Remove all index keys
data = data.replace(/,"length":"[0-9]+"/g,""); //Remove length key-value pair
data = data.replace(/{/g,"["); //Change the left brackets
data = data.replace(/}/g,"]"); //Change the right brackets
return JSON.parse(data);
}

Not magic, but you can loop over the data and test what type of value it has.
A basic example would be as follows. It doesn't have the error checking I'd want in production code though.
var data = {"0":{"0":"image1.jpg","1":"texthere","2":"0"},"1":{"0":"image66.jpg","1":"texthere","2":"1"},"2":{"0":"image12.jpg","1":"texthere","2":"2"},"3":{"0":"image44.jpg","1":"texthere","2":"3"},"4":{"0":"image34.jpg","1":"texthere","2":"4"},"5":{"0":"image33.jpg","1":"texthere","2":"5"},"6":{"0":"image21.jpg","1":"texthere","2":"6"},"7":{"0":"image32.jpg","1":"texthere","2":"7"},"8":{"0":"image13.jpg","1":"texthere","2":"8"},"9":{"0":"image11.jpg","1":"texthere","2":"9"},"10":{"0":"image03.jpg","1":"texthere","2":"10"},"length":"12"};
function data_to_array(data) {
var array = [];
for (var key in data) {
var value = data[key];
if (typeof value === 'string') {
array[key] = value;
} else {
array[key] = data_to_array(value);
}
}
return array;
}
var array = data_to_array(data);
console.log(array);
Make sure you add hasOwnProperty checks if your object prototypes might be messed with. You should probably also add a check to make sure that only integer keys are added to the array.

There is no built-in functions. If you have JSON string, you can do string replacement, otherwise you have to loop as shown below.
var dataObject = {"0":{"0":"image1.jpg","1":"texthere","2":"0"},"1":{"0":"image66.jpg","1":"texthere","2":"1"},"2":{"0":"image12.jpg","1":"texthere","2":"2"},"3":{"0":"image44.jpg","1":"texthere","2":"3"},"4":{"0":"image34.jpg","1":"texthere","2":"4"},"5":{"0":"image33.jpg","1":"texthere","2":"5"},"6":{"0":"image21.jpg","1":"texthere","2":"6"},"7":{"0":"image32.jpg","1":"texthere","2":"7"},"8":{"0":"image13.jpg","1":"texthere","2":"8"},"9":{"0":"image11.jpg","1":"texthere","2":"9"},"10":{"0":"image03.jpg","1":"texthere","2":"10"},"length":"12"};
function getArray(object){
var array = [];
for(var key in object){
var item = object[key];
array[parseInt(key)] = (typeof(item) == "object")?getArray(item):item;
}
return array;
}
var dataArray = getArray(dataObject);

Related

Loop Through PHP Array Encoded In JSON

I have a PHP array that has a table id as the key and a table field as the value.
Example PHP:
while($row = mysql_fetch_array($result))
{
$id = $row['id'];
$array[$id] = $row['some_field'];
}
I then use json_encode($array) to get something like:
{"id1":"value1","abc":"123","xyz":"789"}
How can I loop through this in jQuery? From what I have found so far it seems like I need to know the key. So:
var obj = jQuery.parseJSON(jsonVar);
alert(obj.abc); //prints 123
But how can I get these values if I don't know the keys since they are dynamic?
Do I need to restructure my PHP array?
Once you encode an associative array in php into a JSON object it is no longer an array, it is an object with keys and values. You can iterate through them in javascript using for..in
for (var key in obj) {
console.log(obj[key]);
}
Note: for..in does not garuntee order, if you need to ensure order you will have to make your array indexed, instead of key=>value, and use a for loop (or while) instead.
You can get the keys of your array using Object.keys, then loop through them. Unlike for...in, this gives you the option to .sort() the keys before processing them:
var keys = Object.keys(obj).sort(); // sorting is optional
for (var i=0; i<keys.length; i++) {
var key = keys[i],
val = obj[key];
console.log(key+":"+val);
};
In older browsers, you'll need a polyfill to enable the Object.keys method. MDN has one on their documentation page.

AS#3 organize variables loaded from PhP

I am having a problem of how to organize my variables in flash that are from a PHP script.Ideally i want them in an array type format so i can loop through them.Below is some code to go with.
function completeHandler(evt:Event){ // after loading the php
var symbolsArray:Array = new Array()
symbolsArray.push(evt.target.data.symbol_1);// php variable named: symbol_1, symbol_2
trace(evt.target.data);
}
The above is allworking, the PHP variables are listed as symbol_1, symbol_2 etc
Instead of pushing each variable separably into the array i want a loop, along the lines of:
function completeHandler(evt:Event){
var symbolsArray:Array = new Array()
var counter =1
symbolsArray.push(evt.target.data.symbol_+counter); this is the issue
trace(symbolsArray[0]); //returns NaN
}
Below is the php return vars to flash to give an idea:
$returnVars['symbol_1'] = $virtualReel1[0];
$returnVars['symbol_2'] = $virtualReel1[1];
$returnVars['symbol_3'] = $virtualReel1[2];
$returnVars['symbol_4'] = $virtualReel2[0];
$returnVars['symbol_5'] = $virtualReel2[1];
//etc
$returnString = http_build_query($returnVars);
echo $returnString;
symbolsArray.push(evt.target.data["symbol_"+counter]);
If you need to dynamically query properties of an object, you address it as an Array or a Dictionary, by a string key, which can be dynamically formed. Works on anything.
The returned data can be treated as an Object (containing Objects) so you can loop thru it like so:
function completeHandler(evt:Event)
{
var symbolsArray:Array = new Array();
for each (var obj:Object in evt.target.data)
{
symbolsArray.push(obj);
}
}
If you know all items are oif same type, you can cast the object. eg: if all Numbers:
symbolsArray.push(Number(obj));
Or Strings:
symbolsArray.push(String(obj));

foreach for javascript, json array

I have a JSON array that looks like this:
[{"RegDate":"31-03-2011"},{"RegDate":"29-07-2011"},{"RegDate":"09-08-2011"},{"RegDate":"09-08-2011"},{"RegDate":"09-08-2011"},{"RegDate":"12-08-2011"},{"RegDate":"15-08-2011"},{"RegDate":"15-08-2011"},{"RegDate":"23-08-2011"},{"RegDate":"07-09-2011"},{"RegDate":"09-09-2011"},{"RegDate":"13-10-2011"},{"RegDate":"13-10-2011"},{"RegDate":"13-10-2011"},{"RegDate":"25-10-2011"},{"RegDate":"25-10-2011"},{"RegDate":"03-11-2011"},{"RegDate":"03-11-2011"},{"RegDate":"11-11-2011"},{"RegDate":"16-11-2011"},{"RegDate":"18-11-2011"},{"RegDate":"21-11-2011"},{"RegDate":"02-12-2011"},{"RegDate":"02-12-2011"},{"RegDate":"12-12-2011"}]
The code to get this json array is as of the following:
var unavailableDates1 = jQuery.parseJSON('<?php echo json_encode($noticesDates) ?>');
I am trying too get all of the dates in that array (which was originally a multidimensional array), and put it inside one array:
var unavailableDates = ["9-3-2012", "14-3-2012", "15-3-2012"]; for example
I am unsure of how to do this, I have tried a foreach but wasn't successful.
All help will be appreciated.
First of all, that parseJSON is unnecessary and actually dangerous. Take it out:
var unavailableDates1 = <?php echo json_encode($noticesDates) ?>;
Then, just use jQuery.map:
var unavailableDates = $.map(unavailableDates1, function(item) {
return item.RegDate;
});
Using a string like that is dangerous for the following three objects, for example:
{"key":"Backslash here: \\"}
{"key":"I'm a horse!"}
{"key":"Some\\backslash"}
They become, respectively:
SyntaxError: Unexpected end of input (Single escape escapes end of string)
SyntaxError: Unexpected identifier (Unescaped single quote breaks out of the string, actually an XSS vulnerability)
Object
key: "Someackslash" (\\b becomes the \b backspace control character)
__proto__: Object
You could escape it again, but there's no need; valid JSON is always a valid JavaScript object, and you can trust your own PHP not to include injection code in there.
var justDates = [];
for (var i=0; i < unavailableDates1.length; i++) {
justDates.push(unavailableDates1[i]['RegDate']);
}
Each Object ({'RegDate:'date'}) is an item in a javascript array. To get an item you use a numerical index. so to get the first item would be theArray[0] this would give you {"RegDate":"31-03-2011"}. Then to get that particular date string you just have to use the key theArray[0]['RegDate']!. So since you want to go through every member of a list, you should get the list length using .length.
For loops are usually used for this type of iteration and not for..in. because for in can access properties that are undesired! http://javascriptweblog.wordpress.com/2011/01/04/exploring-javascript-for-in-loops/
have a look at how to iterate over an array.
You can do something like:
dates = new Array();
unavailableDates1.forEach(function (obj){
dates.push(obj.RegDate);
};
Try the following:
JavaScript:
var x = [{"RegDate":"31-03-2011"},{"RegDate":"29-07-2011"},{"RegDate":"09-08-2011"},{"RegDate":"09-08-2011"},{"RegDate":"09-08-2011"},{"RegDate":"12-08-2011"},{"RegDate":"15-08-2011"},{"RegDate":"15-08-2011"},{"RegDate":"23-08-2011"},{"RegDate":"07-09-2011"},{"RegDate":"09-09-2011"},{"RegDate":"13-10-2011"},{"RegDate":"13-10-2011"},{"RegDate":"13-10-2011"},{"RegDate":"25-10-2011"},{"RegDate":"25-10-2011"},{"RegDate":"03-11-2011"},{"RegDate":"03-11-2011"},{"RegDate":"11-11-2011"},{"RegDate":"16-11-2011"},{"RegDate":"18-11-2011"},{"RegDate":"21-11-2011"},{"RegDate":"02-12-2011"},{"RegDate":"02-12-2011"},{"RegDate":"12-12-2011"}];
var ary = new Array();
for (foo in x) {
ary.push(x[foo].RegDate);
}
console.log(ary);
jsFiddle example.
I noticed you tag jquery in here as well so, here's a jquery solution:
http://jsfiddle.net/aztechy/DK9KM/
var foo = [
{"RegDate":"31-03-2011"},
{"RegDate":"29-07-2011"},
{"RegDate":"09-08-2011"},
{"RegDate":"09-08-2011"}
];
var datesArray = [];
$.each(foo, function() {
datesArray.push(this.RegDate);
});
console.log(datesArray);​
Try This, it may works.
var unavailableDates = [];
for(var i = 0; i < unavailableDates1.length; i++){
unavailableDates[i] = unavailableDates1[i].RegDate;
}
for(var i=0;i<unavailableDates.length;i++) {
unavailableDates[i] = unavailableDates[i].RegDate;
}

JavaScript: Remove keys from json object

Example output from PHP:
{
"RootName_0":{"Id":1,"ValId":1,"Value":"Colour","Text":"Blue"},
"RootName_1":{"Id":1,"ValId":2,"Value":"Colour","Text":"Red"}
}
How can I use Backbone.js or jQuery to only have:
[
{"Id":1,"ValId":1,"Value":"Colour","Text":"Blue"},
{"Id":1,"ValId":2,"Value":"Colour","Text":"Red"}
]
If it's easier to use PHP to edit the JSON, then so be it.
Well, in PHP it would be easy, just use array_values() on the initial array so that it 'forgets' the array indexes (which by the way, is what 'RootName_X' is called in your case:
$newvalue = array_values( (array)$value );
echo json_encode($newvalue);
In javascript, it's a bit trickier, but it would be on the lines of:
var newvalue = [];
for(var root in value)
newvalue.push(value[root]);
The question title is was a bit confusing since these are certainly not tags.
No need for jquery or Backbone:
var obj = {
"RootName_0":{"Id":1,"ValId":1,"Value":"Colour","Text":"Blue"},
"RootName_1":{"Id":1,"ValId":2,"Value":"Colour","Text":"Red"}
};
var colors = [];
for(var key in obj){
colors.push(obj[key]);
};
The value you want is now in the colors array.
Using ES5 (modern browsers) you could do:
Object.keys(received).map(function(key) {
return received[key];
});
Basically, converting the object into an array of its keys, then replacing each key with the value.
In javascript, if myFirstVar contains the initial object, then do:
mySecondVar = [ myFirstVar.RootName_0, myFirstVar.RootName_1 ];
Once the JSON has been parsed, do it using jQuery's jQuery.map, and borrowing the global Object function...
var arr = $.map(obj,Object);
EDIT:
If you do it in JavaScript, you should be aware that the objects may not remain in their original order.
You can remedy this if the RootName_n keys are sequential, and you know the n of the last key.
var last_key = 20;
var arr = [];
for(var i = 0; i <= last_key; i++)
arr.push( obj['RootName_' + i] );

how do i dynamically create a multidimensional javascript array

I'm trying to dynamically build a javascript array where _tags is a globally defined array and then send it to php via ajax request. Basically I need the uid as a key and x,y as a sub array. in php it would look something like
$arr[$uid] = array('x'=>$x,'y'=>$y);
but im having trouble figuring out an array like this in javascript, heres what i have
function add_tag_queue(uid,x,y){
var arr = new Array(3);
arr[0] = uid;
arr[1] = x;
arr[2] = y;
_tags.push(arr);
}
This works ok as long as their is only
one entry being added to the array,
I'm adding multiple values, in other
words the function will run a few
times and then i want to send that
entire array, but this seems to just
be adding everything with a comma
delimeter.
Im not sure what youre saying exactly here. The second example i previously gave assumes there is a single x,y pair for each uid but places no limits on how many uids are in _tags. Thats why var _tags = {}; is ourside of the function - so its a global variable.
The following modifications would allow you to have multiple x,y pairs for each uid:
function add_tag_queue(uid,x,y){
/*
* detect if _tags[uid] already exists with one or more values
* we assume if its not undefined then the value is an array...
* this is similar to doing isset($_tags[$uid]) in php
*/
if(typeof _tags[uid] == 'undefined'){
/*
* use an array literal by enclosing the value in [],
* this makes _tags[uid] and array with eah element of
* that array being a hash with an x and y value
*/
_tags[uid] = [{'x':x,'y':y}];
} else {
// if _tags[uid] is already defined push the new x,y onto it
_tags[uid].push({'x':x, 'y':y});
}
}
This should work:
function add_tag_queue(uid,x,y){
_tags.push([uid, x,y]);
}
if you want the uid as the key then you need to use an object/hash not an array
var _tags = {}; // tags is an object
function add_tag_queue(uid,x,y){
_tags[uid] = {'x':x,'y':y};
}
You could always just build it in php and json_encode it.
You're looking to implement an associative array in Javascript. While Javascript does not support associative arrays, Javascript objects can be treated much the same.
Try this instead:
_tags = {}
function add_tag_queue(uid,x,y){
_tags[uid] = {x:x, y:y};
}
_tags is now an object and you'll be adding a new object at the uid key. Likewise, the x,y pair is stored in an object. The first x is the key and the second is the value. To clarify, you could write it like this:
function add_tag_queue(uid,xValue,yValue){
_tags[uid] = {x:xValue, y:yValue};
}
It looks very similar to the PHP example you gave:
function add_tag_queue(uid,x,y){
_tags[uid] = {x: x, y: y};
}
This is how I create multidimensional arrays in JS. I hope this helps.
var arr= [];
arr[uid] = new Array();
arr[uid]["x"] = xvalue;
arr[uid]["y"] = yvalue;

Categories