Manipulation of Javascript objects - javascript

I have an object in my javascript which looks like this:
{"data":[{"t":{
"level":"35",
"longtitude":"121.050321666667",
"latitude":"14.6215366666667",
"color":"#040098"}},
{"t":{
"level":"31",
"longtitude":"121.050316666667",
"latitude":"14.621545",
"color":"#040098"}},
{"t":{
"level":"29",
"longtitude":"121.050323333333",
"latitude":"14.62153",
"color":"#040098"}},
// .....
What I would like to do is to iterate thru the contents of my object so that I will be able to push them to their respective arrays independently.
I have an array for longitude, latitude, color and level.
So I have tried the following:
var size = 0, key;
for (key in result) {
if (result.hasOwnProperty(key)) size++;
alert(result.data[size]);
}
-->But this only alerts me "[object Object]"
success: function(result){
var size = 0, key;
for (key in result) {
for(var attr in key){
alert(attr['latitude']);
}
}
}
-->This gives me Undefined result[key]
I have checked that the size of my object is only 1 thru these codes
var size = 0, key;
for (key in result) {
if (result.hasOwnProperty(key)) size++;
}
alert(size);
I believe that only "data" is being read. And others that are inside "data" are disregarded.
I have read this, this, enter link description here, and this but they sall seem to deal with a different structure of objects. Thanks for the help in advanced.
UPDATE
Using the console.log(), I have confirmed, if im not mistaken that only the first attribute is being fetched
t
Object { level="35", longtitude="121.0508", latitude="14.6204083333333", more...}
color "#040098"
latitude "14.6204083333333"
level "35"
longtitude "121.0508"
I tried this
for (key in result) {
if (result.hasOwnProperty(key)) size++;
console.log(result.data[size]['level']);
}
--> but it says undefined
based on the structure of my object which is
data:[{"t":{'others'},'others'...]
How am I to read everything inside "data"? Each "data" has "t".

Update: Using the for...in construct for iterating over arrays isn't recommended. The alternative is a regular for loop (each method of course having their respective advantages):
for(var i=0; i<results.data.length; i++){
alert(results.data[i]['t']['latitude']);
// etc...
}
Be careful with the structure of your JSON. Also note that the javascript foreach loop iterates over keys/indices -- not values. See demo: http://jsfiddle.net/g76tN/
success: function(result){
var latitudes = [];
// and so on...
for (var idx in result.data ) {
if( result.data.hasOwnProperty(idx) ){
alert( result.data[idx]['t']['latitude'] );
// So you would do something like this:
latitudes.push ( result.data[idx]['t']['latitude'] );
// and so on...
}
}
}​
Note for collecting properties of objects in an array, jQuery $.map() -- or native js array map for that matter -- is a neat, useful alternative.
var latitudes = $.map( result.data, function(n){
return n['t']['latitude'];
});
// and so on...

Assuming result is your object, this should just be a matter of iterating over your data array:
for (var i = 0; i < result.data.length; ++i) {
console.log(result.data[i].t.latitude);
...
}

It's not hard to do, as shown below. But why would you want to take useful objects like your t's and turn them into such arrays?
var levels = [], longitudes= [], latitudes = [], colors = [];
var result = {"data":[{"t":{
"level":"35",
"longtitude":"121.050321666667",
"latitude":"14.6215366666667",
"color":"#040098"}},
{"t":{
"level":"31",
"longtitude":"121.050316666667",
"latitude":"14.621545",
"color":"#040098"}},
{"t":{
"level":"29",
"longtitude":"121.050323333333",
"latitude":"14.62153",
"color":"#040098"}}
]};
var data = result.data;
var i, len, t;
for (i = 0, len = data.length; i < len; i++) {
t = data[length].t;
levels[i] = t.level;
longitudes[i] = t.longtitude;
latitudes[i] = t.latitude;
colors[i] = t.color;
}

See http://jsfiddle.net/VGmee/, which keeps the hasOWnProperty (which is important), and your misspelling of "longitude", which is not.
var data = input.data,
result = {level: [], longtitude: [], latitude: [], color: []};
for (var i = 0, n = data.length; i < n; i += 1) {
var info = data[i].t;
for (var property in info) {
if (info.hasOwnProperty(property)) {
result[property].push(info[property]);
}
}
}
console.log(result.level);
console.log(result.latitude);
console.log(result.longtitude);
console.log(result.color);
This requires the result arrays to actually have the properties in your input array, but you can add error handling as desired.

Related

Javascript get the name of the object after parsing from JSON

Consider the following JSON string:
[{"ElementID1":{"latitude":"10.02483","longitude":"70.753464"}},{"ElementID2":{"latitude":"10.029301","longitude":"70.751892"}},{"ElementID3":{"latitude":"10.029568","longitude":"70.751856"}}]
Which is contained in the "data" variable:
var response = JSON.parse(data);
How do I go through this result?
It is clear for me that I can access this first as an array:
for(var element in response)
{
}
But I don't know what "ElementID1" will be. It can be any string so i cant just do something like
element.elementID.latitude
To retrieve the object latitude. And i would also like to be able to get that picture id itself.
I think this is a simple question but i have tried googling for the answer for a while without any progress.
var data = [{"ElementID1":{"latitude":"10.02483","longitude":"70.753464"}},
{"ElementID2":{"latitude":"10.029301","longitude":"70.751892"}},
{"ElementID3":{"latitude":"10.029568","longitude":"70.751856"}}];
for(var i = 0; i < data.length; i++) {
var obj = data[i];
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
console.log(obj[key].latitude);
}
}
}
DEMO
Basically, you need to access each data array element, which is an object in this case, and since you don't know the name of ElementID* for each element, you can loop through the properties of this object looking for the desired one, latitude in this case.
You can do the following:
response.forEach(function(response){
for (var element in response){
var picutureId = element;
var latitude = value[element].latitude;
var longitude = value[element].longitude;
// at this point you can manipulate the pictureId, latitude, and longitude of each object
}
})
Loop through the results array, loop through each object's key/val pair and manipulate the data from there.
If even latitude and longitude attribute names are unknown
for (var index in data) { //Iterate through array
var obj = data[index];
for (var prop in obj) { //Iterate through ElementId object
console.log(prop); //Print ElementID
var latlongObj = obj[prop];
for (var key in latlongObj) { //Iterate through latlong object
console.log(key); //Print lattitude/longitude
console.log(latlongObj[key]); //Print value
}
}
}

Getting value from json/javascript array of name/value pairs?

I have a JSON array of name/value pairs and I'm looking at a sensible way to be able to adjust the value for a particular name in the array. e.g.
var myArr = [{"name":"start","value":1},{"name":"end","value":15},{"name":"counter","value":"6"},{"name":"user","value":"Bert"}]
I can use
$.each(myArr, function (key, pair) {
if (pair.name == 'user')
{
pair.value = 'bob';
}
});
but in reality my object has tens of values and I would like to be able to change them much more simply than adding an if for each one.
Ideally myArr['user'].value = 'bob'; or something similar.
You have an array of objects in an array. An array does not have any indexing method that gives you direct lookup like you asked for;
myArr['user'].value = 'bob';
To get that, you would need to restructure your data so that you had an object where the name was the main key and inside that key was another object with the rest of your data for that user like this:
var myData = {
"start": {value: 1},
"end": {value: 15},
"user": {value: Bert}
};
The, you could directly access by name as in:
myData['user'].value = 'bob;
If you wanted to stick with your existing data structure, then the simplest thing I can think of is to make a simple function that finds the right object:
function findUser(data, nameToFind) {
var item;
for (var i = 0; i < myArr.length; i++) {
item = nameToFind[i];
if (item.name === nameToFind) {
return item;
}
}
}
var myArr = [{"name":"start","value":1},{"name":"end","value":15},{"name":"counter","value":"6"},{"name":"user","value":"Bert"}]
Then, you could do something like this:
findUser(myArr, "user").value = "bob";
This assumes you're only looking for data that is in the array because otherwise, this will create an error unless you add error checking to it.
If you just really want to turn the whole thing into a function that finds and changes the name, it can be like this:
function changeUser(data, nameToFind, newName) {
var item;
for (var i = 0; i < myArr.length; i++) {
item = nameToFind[i];
if (item.name === nameToFind) {
item.name = newName;
return;
}
}
}
I will award the points for the best answer, but I actually solved it a completely different way:
First build up a list of "names" in the order they appear:
var keys = [];
$.each(myArr, function (key, pair) {
keys.push(pair.name);
});
then I can use:
myArr[keys.indexOf('sEcho')].value = 'whatever';
Try This
$.grep(myArr,function(e){return e.name=="user"})[0].value="ppp"
You can use the $.greb() of jquery.
Add this function:
function SetArrayValue(arr, key, value, stopOnFirstMatch) {
for (var i=0; i<arr.length; i++) {
if (arr[i].name === key) {
arr[i].value = value
if (stopOnFirstMatch !== undefined && stopOnFirstMatch) return
}
}
}
Then use it this way:
SetArrayValue(myArr, 'user', 'bob')

Converting multidimensional object array to JSON

I have an array of object which i want to convert to a JSON string but i recieve the following error: JavaScript exception :Uncaught TypeError: Converting circular structure to JSON
From what i understand this is because there is a loop in references. i've searched here on SO for solutions and someone came up with a 'replace function'. this looked something like this:
var cache = [];
JSON.stringify(o, function(key, value) {
if (typeof value === 'object' && value !== null) {
if (cache.indexOf(value) !== -1) {
// Circular reference found, discard key
return;
}
// Store value in our collection
cache.push(value);
}
return value;
});
cache = null; // Enable garbage collection
but using this gives me the following error: Maximum call stack size exceeded.
i think this solution doesn't really fits my needs, because i am not intrested in all the elements ofthe array that i'm trying to convert. These elements are added are 3rd party(google maps) so i have no influence on their child objects.
This is a screenshot of my array object:
i am only interested in the following items:
Tour
-id
-name
-days :
-id
-name
-markers :
-dayId
-title
-position :
-nb
-ob
-thumbs :
- 0
- 1
- ...
because the object array is created by several functions/services/factories is it difficult to make a fiddle or provide some code samples.
Any sugestion how to convert an array like this to JSON is welcome, thanks in advance
For anyone interested, i ended up making my own array with just the elements that i needed:
function CreateJson(tour){
var sJson = {};
sJson.name = tour.name;
sJson.id = tour.id;
sJson.days = [];
sJson.markers = [];
sJson.thumbs = [];
for(i = 0; i < tour.days.length; i++){
sJson.days.push({
id: tour.days[i].id,
name: tour.days[i].name
});
for(j = 0; j < tour.days[i].markers.length; j++){
sJson.markers.push({
id: tour.days[i].markers[j].id,
dayId: tour.days[i].markers[j].dayId,
name: tour.days[i].markers[j].title
});
}
for(k = 0; k < $scope.thumbs.length; k++){
sJson.thumbs.push($scope.thumbs[k])
}
};

Sort JSON array based on value with jQuery

I've got two dropdown select dropdowns: one for regions and one for cities in the selected region. The result is loaded by AJAX and in my response i get all cities in an JSON array:
{
1709: "Geertruidenberg",
1710: "Netersel",
1711: "Macharen",
1712: "Beers",
1713: "Hank",
1714: "Oudemolen",
1715: "Nistelrode"
}
I'm using this small plugin to load the data in the select dropdown:
(function($, window) {
$.fn.replaceOptions = function(options) {
var self, $option;
this.empty();
self = this;
$.each(options, function(index, option) {
$option = $("<option></option>")
.attr("value", index)
.text(option);
self.append($option);
});
};
})(jQuery, window);
And this piece of javascript to do the AJAX request:
$('select#Profile_regionId').change(function() {
$.post('/ajax/getcities', {regionid: $(this).val()}, function(data){
//console.log(data.cities);
$("select#Profile_cityId").replaceOptions(data.cities);
}, 'json');
});
All works totally fine, except the city dropdown is automatically sorted on the JSON array key. I tried to use the sort() method for this, but it won't work because it's an Object and not an array. Then i tried to create an array of it:
var values = [];
$.each(data.cities, function(index,value)) {
values[index] = value;
}
But for some reason, the dropdown list fills itself up from 1 to the first found id (key of array) of the city, and i don't know why it's doing that (array itself looks fine).
How can i sort the thing so my cities are ordered alphabetically in the dropdown list?
It needs to be converted to an array so that it can be sorted. Let's assume this is your object. Note that I rearranged it to be unsorted, to prove this works.
originalData = {
1712: "Beers",
1709: "Geertruidenberg",
1710: "Netersel",
1713: "Hank",
1714: "Oudemolen",
1711: "Macharen",
1715: "Nistelrode"
};
Now to create an array version we need to create an array, and insert objects into it. I'm calling the keys "year". Note that we're calling parseInt on the keys. Keys in JavaScript (except for arrays) are always strings. For example, {foo: "bar"} has a string key "foo". This also applies to numerical looking keys.
var dataArray = [];
for (year in originalData) {
var word = originalData[year];
dataArray.push({year: parseInt(year), word: word});
}
There's a chance that we have our data out of sort right now, so we manually sort it. Note that this is a case sensitive sort. For example, "Qux" comes before "foo".
dataArray.sort(function(a, b){
if (a.word < b.word) return -1;
if (b.word < a.word) return 1;
return 0;
});
The function now just pulls option.year and option.word from our array.
$.fn.replaceOptions = function(options) {
var self, $option;
this.empty();
self = this;
$.each(options, function(index, option) {
$option = $("<option></option>")
.attr("value", option.year)
.text(option.word);
self.append($option);
});
};
And then you finally use the plugin, passing the array. You can put all of this code in the plugin, if that works best for you.
$('#mylist').replaceOptions(dataArray);
fiddle
This will do what you want and take care of the empty ids/undefined values:
var data = {
1709: "Geertruidenberg",
1710: "Netersel",
1711: "Macharen",
1712: "Beers",
1713: "Hank",
1714: "Oudemolen",
1715: "Nistelrode"
};
var values = [];
$.each(data, function(index, value) {
values[index] = value;
});
values.sort();
$.each(values, function(index, value) {
if(value != undefined) {
$("#Profile_cityId").append("<option>"+ value +"</option");
}
});
Just replace the append I put in with your own function because jsFiddle was giving me trouble using that. Demo: http://jsfiddle.net/R4jBT/3/
So here is how I would do it. I assume that you are getting an AJAX response that comes like:
results: [
{year: 1709, city: "Geertruidenberg"},
{year: 1710, city: "Netersel"},
{year: ..., city: ...}
]
And, in a standard AJAX call, you would run through them like this, in a success function:
success: function(data) {
var results = data.results;
if (results.length > 0) {
for (i=0; i < results.length; i++) {
dataArrayOrig.push({
"id" : results[i].year,
"label" : results[i].city
});
}
}
},
I saw you say you do your call like this:
$.post('/ajax/getcities', {regionid: $(this).val()}, function(data){
//console.log(data.cities);
$("select#Profile_cityId").replaceOptions(data.cities);}, 'json');
You're not doing anything tests on data to see if it has results (ex. if (data.length > 0) { ... }), and you would need to push those results to an original array that stays pristine and another that can be sorted, then a final one that can get back the original year to the label, that the dropdown can then receive.
If you do it as I showed, above, you can integrate the lines I gave into the function(data){ ... } area.
Right after the push to the dataArrayOrig object, you can push to a new array you can use to sort with, using a comparison function to determine if the label (city) should come before or after the previous entry:
var results = data.results;
if (results.length > 0) {
for (i=0; i < results.length; i++) {
dataArrayOrig.push({
"id" : results[i].year,
"label" : results[i].city
});
dataArraySorting.push({
"id" : results[i].year,
"label" : results[i].city
});
dataArraySorting.sort(compare);
JSON.stringify(dataArraySorting); // sorted cities, but will be mismatched to the years
}
}
The comparison function:
function compare (a, b) {
if (a.label < b.label)
return -1;
if (b.label < a.label)
return 1;
return 0;
});
You could also do this inline:
dataArraySorting.sort(function(a, b){
if (a.label < b.label) return -1;
if (b.label < a.label) return 1;
return 0;
});
I prefer the function approach since then it can be re-used. We will see the usefulness of that in a minute.
For your arrays, declare them at the top, before your functions:
var dataArrayOrig = [];
var dataArraySorting = [];
var dataArraySorted = [];
So after that loop that goes through the results, start another one that goes through the "sorting" array and compares its label against the one in the original array we pushed to and pulls out the original ID (Year):
for (var j=0; j < dataArraySorting.length; j++) {
for (var k=0; k < dataArrayOrig.length; k++) {
if (dataArraySorting[j].label == dataArrayOrig[k].label) {
dataArraySorted.push({
"id" : dataArrayOrig[k].id,
"label" : dataArraySorting[j].label
});
console.log("Sorted ID: " + dataArrayOrig[k].id + ", Sorted label: " + dataArraySorting[j].label);
dataArraySorted.sort(compare);
JSON.stringify(dataArraySorted); // array of sorted cities, matched to year
}
}
}
You would go on to apply that dataArraySorted array to your dropdown as normal. I tested to see if I got more than 0 items from the original AJAX call, then I appended the options using id and label from the array's property names:
if (dataArraySorted.length > 0) {
$.each(dataArraySorted, function() {
$("#combobox").empty().append($("<option></option>").val(this['id']).html(this['label'));
});
}
JSFiddle with the results.

Map values from external json lookup into array as new key/value pairs

I am trying to map new values (from an external json file) into an array (array of arrays or KV pairs, generated from a php file query to mysql) in javascript/jQuery.
The structure of the array is:
"results":
[{"gender":"Male","DOB":"1993-09-22","location":"Main","procCode":"43653","preopDx1":"783.3","procedDate":"2008-06-02"},{"gender":"Female","DOB":"2001-11-07","location":"South","procCode":"11403","preopDx1":"216.5","procedDate":"2010-01-01"},...]
The json file looks like this:
[
{
"CPT": "10021",
"RVU": "1.27"
},
{
"CPT": "10022",
"RVU": "1.27"
}
]
The idea is to
a) Loop thru the myarray values and find each procCode
b) Match this procCode with the identical cpt code in the json file, and
c) Attach each new key/value pair to each 'row' of myarray
function addRVU (myarray, myjson){
var newObj = $.map(myarray, function (i,res){
if(myarray[i].procCode == myjson[i].CPT){
return myarray[i].RVU = myjson[i].RVU;
}
}
}
Thanks in advance!
// First, convert JSON file into an object keyed off CPT code:
var jsonObj = {};
for (var i = 0; i < json.length; i++) {
jsonObj[json[i].CPT] = json[i];
}
// Now update myarray elements
for (i = 0; i < myarray.length; i++) {
// $.extend copies properties from 2nd object into 1st object
$.extend(myarray[i], jsonObj[myarray[i].procCode]);
}
for if(myarray[i].procCode == myjson[i].CPT), you only matched the json and array with same index. loop to match all element in json should fix your problem.
or something like using a hash to map the RVU
h = {};
$.each(json, function(i, e){
h[e.CPT] = e.RVU;
});
$.each(ar, function(i, e){
e.RVU = h[e.procCode];
});

Categories