JSON parsing in Javascript with no known number of items - javascript

I'm drawing a blank with the best way to process JSON data which will be of the following form:
[{"latlng":"42.6674996,-71.1786423"},
{"latlng":"53.8136722,-1.7301123"}]
var p = '[{"latlng":"42.6674996,-71.1786423"},
{"latlng":"53.8136722,-1.7301123"}]',
It will also be of variable length.
I'm having trouble looking through all the data pairs pulling off the latlng values.
I'm using the code:
for (var key in p) {
if (p.hasOwnProperty(key)) {
alert(key + " -> " + p[key]);
}
}
from this other SO question: How do I loop through or enumerate a JavaScript object?
However, the formats in the above example are different from mine.
How do I loop through each key/value in turn until the JSON string is exhausted?
I'm a little new to JSON and Javascript.

You can always use JSON.parse (on any remotely modern browser) to take a json string and get the relevant javascript structure. Once you have that, you can iterate over the structure.
So you start with
var json = '[{"latlng":"42.6674996,-71.1786423"}, {"latlng":"53.8136722,-1.7301123"}]';
and then you can get a javascript array by
var ary = JSON.parse(json);
From here you are just a hop skip and jump away from iterating over your array, getting the current element, and doing what you want.
Note for your structure, instead of returning
{"latlng":"42.6674996,-71.1786423"}
for each element in the array, you should do
{"lat":"42.6674996","long": "-71.1786423"}
that way as you iterate over the array, you can do something like
...in your for loop
var current = ary[i];
var lat = current.lat;
var long = current.long;

Use the jQuery.parseJSON - jQuery API:
var json = '[{"latlng":"42.6674996,-71.1786423"},{"latlng":"53.8136722,-1.7301123"}]';
var parsed = $.parseJSON(json);
$.each(parsed, function(index, value) {
console.log(value['latlng']);
});
or the native JSON.parse:
var json = '[{"latlng":"42.6674996,-71.1786423"},{"latlng":"53.8136722,-1.7301123"}]';
var parsed = JSON.parse(json);
var count = parsed.length;
for (var i = 0; i < length; i++)
console.log(parsed[i]['latlng']);

You're going to have to turn that string into an object before you can iterate through it safely:
var p = JSON.parse('[{"latlng":"42.6674996,-71.1786423"}, {"latlng":"53.8136722,-1.7301123"}]');
for(key = 0; key < p.length; key++) { // Start the key at zero, increment until it his the object's length
if (p.hasOwnProperty(key)) { // If the item has a key
alert(key + " -> " + p[key]); // Alert the key and then the item.
}
}
In your case, you have a multidimensional object. So each return will give you another object. How I would deal with this is by traversing the returned object like so:
alert(p[key]['latlng']);
To have a better understanding of this, look at the initial object syntax...
[
{ // key 0
"latlng": "42.68, -71.18" // key 'latlng'
},
{ // key 1
"latlng": "53.81, -1.73" // key 'latlng'
}
]
So essentially you're traversing the object using the values that the loop increments. If you have an object with 5 items your loop will grab that number and cycle through 5 times (0 .. 4). Each time it loops the incremented key variable will be used to select your item, and from there you can grab the the latlng key and return its value within the nested object.

Related

extract data of interest from array object

i am trying to extract specific data from an array object using keys but all the data gets returned? why is that? i want to print to the console all the values corresponding to the key genestart only
for (var i=0; i<genedata.matches.length;i++){
var arr = genedata.matches[i];
for (var key in arr){
var attrName=key;
var attrValue = arr[key];
//console.log(attrValue);
if (attrName='genestart'){
console.log(attrValue);
}
}
}
Your if statement is not a comparison but an assignment. Change = to ==

JavaScript. How can I parse a string of vars and turn it into an object with properties

I am trying to parse a string in JS with a series of vars inline. The goal is to turn those vars into an object with name value pairs.
Example:
var hwStr = "color=blue+coreCnt=4+shell=aluminum+wireless=false";
I know I can parse the original string to get an array of name value pairs like this:
varArr = hwStr.split("+");
When I print that array I would get:
>color=blue,
>coreCnt=4,
>shell=aluminum,
>wireless=false
In order to create this object manually it would look like:
var hwSpec = {color: 'blue', coreCnt: 4, shell: 'aluminum', wireless: false};
My question is, how can I use a foreach statement to create an object that would have these as name value pairs.
To be fair JS is not my language, but I know that I SHOULD know this... This is probably a noob Question, any help would be great.
Gary C aka the UnKulMunki
After splitting on the plus signs, you can .reduce() the resulting array to process each key=value pair and add to an object:
var hwStr = "color=blue+coreCnt=4+shell=aluminum+wireless=false";
var obj = hwStr.split("+").reduce(function(o, item) {
item = item.split("=");
o[item[0]] = item[1];
return o;
}, {});
console.log(obj);
This is similar to using .forEach(), except instead of creating an empty object in a variable before calling .forEach() the empty object is passed as an argument to .reduce(). For this particular problem it doesn't make much difference, but in some cases .reduce() saves you having to create a temporary working variable.
EDIT: Note that my code creates all property values as strings - I don't think there's any way to know whether false should be treated as the boolean false or the string "false", unless you want to assume that all values that can be parsed as boolean or number should be treated as boolean or number.
First, you split the string at the + so you get an array of key/value pairs.
Then, you loop through those pairs and split each pair at the = to separate the key from the value. Then you assign the key as a property name and the value as the property value.
var hwStr = "color=blue+coreCnt=4+shell=aluminum+wireless=false";
// Split the string into an array of key/value pairs
var pairs = hwStr.split("+");
// Set up a new, empty object
var newObj = {};
// Loop through the key/value pairs array. The .forEach method takes
// a function as an argument that, itself, receives a value representing
// the current array item being iterated (a single key/value pair from
// the array in this case).
pairs.forEach(function(pair){
// Create a new property on the object with the key of the current pair
// and a value of the value of the current pair.
newObj[pair.split("=")[0]] = pair.split("=")[1];
});
console.log(newObj);
To do this, you have to use JSON's parse method to turn the string to javaScript object literal, this is how to do it:
var arr = hwStr.split("+");
var temp_arr = null;
var hwSpec = null;
var stringToConv = '{'; //string to convert to object literal
//iterate through the array
for (var i = 0; i < arr.length; i++){
temp_arr = arr[i].split("=");
stringToConv += '"' + temp_arr[0] + '":"' + temp_arr[1] + '"';
//check if is the last string in the arr
if (i === arr.length - 1){
stringToConv += '}'
}
else { //add comma
stringToConv += ",";
}
}
//convert to object using JSON
hwSpec = JSON.parse(stringToConv);
//your code here

Looping over associative array

I'm adding a bunch of input fields into an associative array. I can access the individual elements fine, eg. this works:
arr = new Array();
field = document.getElementById("someField");
arr[field] = someValue;
alert(arr[field].id);
But when I try to loop over them, the id shows up as undefined, and only one element is looped over.
for (var elem in arr) {
alert(elem.id + " " + arr[elem]);
}
Am I looping over it wrong?
Edit: arr.length shows up as 0 for some reason even though I'm able to access its elements.
the key in a javascript-array has to be a number or string.
field is automatically converted to a string with toString().
arr = new Array();
field = document.getElementById("someField");
var key = field.toString();
arr[key] = someValue;
alert(arr[key].id);
in your for-loop, you iterate the keys of that array.
field.toString() in that case.
and a string does not have a id-property.
this will work:
for (var elem in arr) {
alert(arr[elem].id + " " + arr[elem]);
}
by the way toString() of a DOM-Element ist often a generic string like "[SpanElement]".
if you try to add multiple span-elements, you're effectivle overriding the item with "[SpanElement]" as key and end up with just one element.
in respect to #user2736012 comments, i encourage everyone to read
"JavaScript Associative Arrays Demystified"
Any associative array in JavaScript is an object. Arrays are objects that have special methods because they are numerically indexed. So your code should look something like this:
obj = {};
field = document.getElementById("someField");
obj[field] = someValue;
for (var p in obj) {
alert(obj[p].id);
}

Can't reference array by index

I have an array defined as:
var subjectCache = [];
I then have some code to build it up, which is working ok.
However, if I try to reference the array by an index, e.g.:
var x = subjectCache[0];
or
var x = subjectCache[1];
I get undefined.
Also subjectCache.length is always 0 (zero).
if I try to reference it by its key, e.g.:
var x = subjectCache['12345'];
it works.
Is this normal? Shouldn't I be able to reference it by its index whatever?
I'm using Internet Explorer, if it makes a difference (and it probably does :( )
[Edit]
this is the code I'm using to build the array, although I really don't think it is to blame.
It's a callback from a webservice call. This is working fine and the array is being populated.
var subjectCache = [];
var subjectCacheCount = 0;
function refreshSubjectsCallback(data) {
// update subjects
// loop through retrieved subjects and add to cache
for( i=0; i < data.length; i++ )
{
var subject = data[i];
var subjectid = subject.SubjectId;
subjectCache[subjectid] = subject;
subjectCacheCount += 1;
}
}
[/Edit]
You're probably assigning keys manually instead of using subjectCache.push() to add new elements to the array:
var array = [];
array['foo'] = 'bar';
console.log(array.length); // 0
The length attribute isn't going to reflect those changes the way you'd expect:
> var a = [];
undefined
> a[100] = 2; // The previous `100` entries evaluate to `undefined`
2
> a.length;
101
Instead, use an object:
var object = {};
object['foo'] = 'bar';
for (var key in object) {
var value = object[key];
console.log(value);
}
From your symptoms, it sounds like you are trying to treat the array as an associative array.
In Javascript, arrays work like this:
var a = [];
a[1] = 10;
alert(a.length);
Objects work like this:
var o = {};
o.myProp = true;
o["myOtherProp"] = false;
Arrays only work with numeric keys not strings. Strings assign properties to the object, and aren't counted as part of length nor it's numeric indices.
When building the array, make sure you are assigning to a numeric position within the array.
No, it will not work, because you haven't created arrays but objects.
you will have to access it by its key.
var x = subjectCache['12345'];
If this works and subjectCache.length doesn't, I think you are making an object not an array. You are confused.
Somewhere along the road you lost the array, and the variable subjectCache points to a different kind of object.
If it was an array, it can't have the length zero and contain an item that is reachable using subjectCache['12345']. When you access an item in an array it doesn't make any difference if you use a numeric index or a string representing a number.

Javascript putting values in two-dimensional array

Is there a better way to create a two-dimensional array in javascript than this?
var divcookies = new Array();
divcookies[0] = new Array(2);
divcookies[0][0] = name;
divcookies[0][1] = value;
This results in a two dimensional array with bad data added in the middle of it. I expect an array like this.
(name1, value1, name2, value2, name3, value3)
Instead I get this.
(name1, value2, ,name2, value2, name3, value3)
I don't really know when that extra bad data is added because if I alert during the loop that fills the array it only seems to loop through 3 times to put the three pairs of values expected.
So I am looking for a different way to get the two dimensional array.
function get_cookies_array() {
var divcookies = new Array();
if (document.cookie && document.cookie != '') {
var split = document.cookie.split(';');
for (var i = 0; i < split.length; i++) {
var name_value = split[i].split("=");
name_value[0] = name_value[0].replace(/^ /, '');
if ( name_value[0].search("compage") != -1 ) {
alert (divname+" "+ divarray);
divcookies[i] = new Array(2);
divcookies[i][0] = decodeURIComponent(name_value[0]);
divcookies[i][1] = decodeURIComponent(name_value[1]);
}
}
}
alert (divcookies);
return divcookies;
}
jsBin http://jsbin.com/iwuqab
The recommended method for creating arrays in JS is to NOT use the 'new' method. Instead, do:
var divcookies = [];
divcookies[0] = [];
divcookies[0][0] = name;
divcookies[0][1] = value;
This notation frees you up from having to specify element numbers in advance. Once a variable's been initialized as an array, you can set any index you want. The downside (regardless of which notation you use) is that you have to initialize every sub-array as well.
Your 2-dimensional array is set up correctly (well, [] is preferred instead of new Array()). The actual problem is only with the display of your array using alert(divcookies). Here, divcookies is converted to a string using the predefined method toString(). This method creates a list of comma-separated array elements, from the first element to the last element. If some elements in between are not set, an empty string is output. In your case, you are not assigning to those indexes i of divcookies for which name_value[0].search("compage") == -1. These are the gaps ,, in the alerted list.

Categories

Resources