loop a JS Object - javascript

I have this JS object:
{
"data": {
"nid": [{
"cid": "32",
"uid": "780",
"comment": "text"
}]
},
"request_status": "found"
}
how can I loop through these items to get comment value ("comment":"text")?

You don't really need to loop to get it. Just do...
var obj = {"data":{"nid":[{"cid":"32","uid":"780","comment":"text"}]},"request_status":"found"};
var text = obj.data.nid[0].comment;
Or if there are several, you can use forEach...
obj.data.nid.forEach(function(val,i) {
alert( val.comment );
});
Or a traditional for loop...
for( var i = 0; i < obj.data.nid.length; i++ ) {
alert( obj.data.nid[i].comment );
}
Or if you want to build an Array, use map...
var arr = obj.data.nid.map(function(val,i) {
return val.comment;
});
Or again a traditional for loop...
var arr = []
for( var i = 0; i < obj.data.nid.length; i++ ) {
arr.push( obj.data.nid[i].comment );
}

Given:
var obj = {
"data": {
"nid": [{
"cid": "32",
"uid": "780",
"comment": "text"
}]
},
"request_status": "found"
};
The direct way to retrieve the comment is:
obj["data"]["nid"][0]["comment"]
// or
obj.data.nid[0].comment
As far as "looping" through the items to get the value, I'm not sure how a loop makes sense. Are you saying you might not know the structure of the object but you know it will have a "comment" field in there somewhere?
The "nid" array only has one item in it - if this was just a sample but really you'll have an array with more values you can loop through that array:
var nid = obj["data"]["nid"], // get a direct reference to the array to save
i; // repeating obj.data.nid everywhere
for (i=0; i < nid.length; i++) {
// do something with the comment in the current item
console.log(nid[i]["comment"]);
}

If you're just referring to that specific object (or if every object you are working with follows that same pattern), then you can just access the value directly:
var theObj = {"data":{"nid":[{"cid":"32","uid":"780","comment":"text"}]},"request_status":"found"};
alert(theObj.data.nid[0].comment);
If you want to do something iterative, then perhaps try this:
var theObj = {"data":{"nid":[{"cid":"32","uid":"780","comment":"text"}]},"request_status":"found"};
for (var index = 0; index < theObj.data.nid.length; index++) {
var item = theObj.data.nid[index];
if (item.comment) {
alert(item.comment);
}
}
Or if you really want to do the entire thing iteratively:
window.searchObj = function(theObj) {
if (theObj.comment) {
alert(theObj.comment);
}
if (theObj instanceof Array) {
searchArray (theObj);
}
else if (theObj instanceof Object) {
for (var key in theObj) {
searchObj(theObj[key]);
}
}
};
window.searchArray = function(theArray) {
for (var index = 0; index < theArray.length; index++) {
var item = theArray[index];
searchObj(item);
}
};
var theObj = {"data":{"nid":[{"cid":"32","uid":"780","comment":"text"}]},"request_status":"found"};
searchObj(theObj);

Related

How to iterate over an array in an array

I want to iterate over my 'areasarray' in the array 'areas' dataprovider array,
I have no idea how to loop over an array in an array, I've tried several tries with for-loops but none of it succeeded.
this is amCharts Maps framework.
var areasarray = {};
//get JSON File
$(function getData() {
var url = "../assets/document.json";
$.ajax({
url: url,
dataType: 'json',
success: function (data) {
console.log(data);
for (var i = 0; i < data.fact.length; i++) {
if (inverseCountryCodes[data.fact[i].dims.COUNTRY] != null) {
areasarray[i] = {
"id": inverseCountryCodes[data.fact[i].dims.COUNTRY],
"value": data.fact[i].Value,
"info": "Verkeersdoden per 100 000 inwoners: " + data.fact[i].Value
}
}
}
//console.log(areasarray);
//Map initialiseren
var map;
map = new AmCharts.AmMap();
map.colorSteps = 20;
var dataProvider =
{
mapVar: AmCharts.maps.worldLow
areas: [
{
id: "BE",
value: 10,
info: "Verkeersdoden ..."
}
]
};
console.log(dataProvider);
map.areasSettings = {
autoZoom: true,
selectedColor: "#338DAB"
};
map.dataProvider = dataProvider;
var valueLegend = new AmCharts.ValueLegend();
valueLegend.right = 10;
valueLegend.minValue = "little";
valueLegend.maxValue = "a lot!";
map.valueLegend = valueLegend;
map.addListener("clickMapObject", function (event) {
document.getElementById("info").innerHTML = '<p><b>' + event.mapObject.title + '</b></p><p>' + event.mapObject.info + '</p>';
});
map.mouseWheelZoomEnabled = true;
map.write("mapdiv");
}
});
});
If you want to iterate over areasarray which is actually an object and not an array you should look into using a for...in loop
For iterating over arrays within arrays, one approach would be to nest for loops
for(var i = 0; i < array1.length; i++) {
for(var j = 0; j < array2.length; j++) {
// do something
}
}
It's not clear to me what you mean by "array in an array" in this context and it would help if you provided more information about what exactly you are trying to accomplish
I would try a nested loop. Here is an example of creating an array of arrays and then looping through each.
var matrix = []
matrix[1] = []
matrix[1][1] = "foo"
matrix.forEach(function(column){
column.forEach(function(cell){
console.log(cell);
});
});
var areasarray = {}; means it's an object, not an array.
To iterate through each items in this object, try this.
var keys = Object.keys(areasarray);
keys.forEach(function(k) {
// you can access your item using
// k is the property key
console.log(areasarray[k]);
console.log(areasarray[k].id);
console.log(areasarray[k].value);
console.log(areasarray[k].info);
});
Not sure why you chose to create areasarray as an object.
If you wanted to, you could have defined it as:
var areasarray = [];
Then when adding to the array you use:
areasarray.push({
"id": inverseCountryCodes[data.fact[i].dims.COUNTRY],
"value": data.fact[i].Value,
"info": "Verkeersdoden per 100 000 inwoners: " + data.fact[i].Value
});
So later on, you can simply do:
for (var i = 0; i < areasarray.length; i++) {
console.log(areasarray[i]);
console.log(areasarray[i].id);
console.log(areasarray[i].value);
console.log(areasarray[i].info);
}
Note: in the above code, i is an index, where in the object block code, k is a key to the object.
Use nested loops.
Example:
var a1=["1","2","3","4","5","6","7"];
var a2=["a","b","c","d","e"];
for(var i=0;i<a1.length;i++) //loop1
{
console.log(a1[i]);
for(var j=0;j<a2.length;j++) //loop2
{
console.log(a2[j]);
}
}
Sample Output:
1st iteration of loop1:
1abcde
2nd iteration of loop1:
2abcde
and so on...
For every iteration of loop1,loop2 iterates 4 times(j<5).
Hoping I got your question right...This could be an answer.!

get values in pairs from json array

Firstly, this is my json value i am getting from a php source:
[{"oid":"2","cid":"107"},{"oid":"4","cid":"98"},{"oid":"4","cid":"99"}]
After that, I want to get and oid value along with the corresponding cid value for example, oid=2 and cid=107 at one go, oid=4 and cid=98 at another and so on. I am trying to use jquery, ajax for this.
I have tried many answers for this, like: Javascript: Getting all existing keys in a JSON array and loop and get key/value pair for JSON array using jQuery but they don't solve my problem.
I tried this:
for (var i = 0; i < L; i++) {
var obj = res[i];
for (var j in obj) {
alert(j);
}
but all this did was to return the key name, which again did not work on being used.
So, you have an array of key/value pairs. Loop the array, at each index, log each pair:
var obj = [{"oid":"2","cid":"107"},{"oid":"4","cid":"98"},{"oid":"4","cid":"99"}];
for (var i = 0; i < obj.length; i++) {
console.log("PAIR " + i + ": " + obj[i].oid);
console.log("PAIR " + i + ": " + obj[i].cid);
}
Demo: http://jsfiddle.net/sTSX2/
This is an array that you have //lets call it a:
[{"oid":"2","cid":"107"},{"oid":"4","cid":"98"},{"oid":"4","cid":"99"}]
To get first element :
a[0] // this will give you first object i.e {"oid":"2","cid":"107"}
a[0]["oid"] // this will give you the value of the first object with the key "oid" i.e 2
and so on ...
Hope that helps.
`
Basically what you need is grouping of objects in the array with a property. Here I am giving two functions using which you can do this
// To map a property with other property in each object.
function mapProperties(array, property1, property2) {
var mapping = {};
for (var i = 0; i < data.length; i++) {
var item = data[i];
mapping[item[property1]] = mapping[item[property1]] || [];
mapping[item[property1]].push(item[property2]);
}
return mapping;
}
// To index the items based on one property.
function indexWithProperty(array, property) {
var indexing = {};
for (var i = 0; i < data.length; i++) {
var item = data[i];
indexing[item[property]] = indexing[item[property]] || [];
indexing[item[property]].push(item);
}
return indexing;
}
var data = [{
"oid": "2",
"cid": "107"
}, {
"oid": "4",
"cid": "98"
}, {
"oid": "4",
"cid": "99"
}];
var oidCidMapping = mapProperties(data, "oid", "cid");
console.log(oidCidMapping["2"]); // array of cids with oid "2"
var indexedByProperty = indexWithProperty(data, "oid");
console.log(indexedByProperty["4"]); // array of objects with cid "4"
May not be the exact solution you need, but I hope I am giving you the direction in which you have to proceed.
If you are willing to use other library you can achieve the same with underscorejs

Recursive function is not capturing parent DOM node attributes

I wrote a recursive function that traverses nested DOM nodes of the following form:
<a href="#" title="test">
<div id="nested-image">
<img src="image.jpg" />
</div>
</a>
The recursive function is the following:
function getNestedNodes(nodeList) {
var ary = [];
for(var i = 0; i < nodeList.length; ++i) {
var myJSONChildren = {};
if(nodeList[i].childElementCount) {
var htmlCollection = nodeList[i].children;
for(var j = 0; j < htmlCollection.length; ++j) {
for(var k =0, attrs = htmlCollection[j].attributes, l = attrs.length; k < l; ++k) {
myJSONChildren['tag'] = htmlCollection[j].nodeName;
myJSONChildren[attrs.item(k).nodeName] = attrs.item(k).nodeValue;
};
}
myJSONChildren['children'] = getNestedNodes(htmlCollection);
ary.push(myJSONChildren);
};
}
return ary;
}
so if I call that function this way:
var links = document.querySelectorAll('a');
console.log(JSON.stringify(getNestedNodes(links)));
it should return a JSON array of the following form:
[{
tag:'a',
href:"#",
title:"test",
children:[{
tag:"div",
id:"nested-image",
children:[{
tag:"img",
src:"image.jpg"
}]
}]
}]
}]
However, it is only returning one of the following form:
[{
"tag":"DIV",
"id":"nested-image",
"children":[{
"tag":"IMG",
"src":"https://www.gravatar.com/avatar/d1a336ae4b6876a4c5c044ec17876ce0",
"children":[]
}]
}]
and I haven't been able to get the form that I want in a proper way without getting empty results, or duplicate results.
Also, I'd like to optimize my recursive function, I'm sure that I can be refactored into something more readable.
Here's a fiddle for you to see:
http://jsfiddle.net/DfHqv/
Any help will be greatly appreciated!
The problem is that you've made your function to anticipate receiving a collection, yet you're looping two node collections within.
So it seems that you're not pushing in the nodes from the outer loop, but only the children. This would explain why you're not getting the top level.
Just keep it to a single loop of nodes (and then the one for attributes, of course), and then instead of looping the children within a new loop, just pass it in the recursive call.
function getNestedNodes(nodeList) {
var ary = [];
// Loop the collection of nodes
for(var i = 0; i < nodeList.length; ++i) {
var node = nodeList[i];
// Create the new object with the "tag" populated
var jsonNode = {"tag":node.nodeName};
// Add the attributes to the object
for(var k =0, attrs = node.attributes, l = attrs.length; k < l; ++k) {
jsonNode[attrs.item(k).nodeName] = attrs.item(k).nodeValue;
}
// Make a recursive call if any children are present, and add the result
if (node.children && node.children.length)
jsonNode['children'] = getNestedNodes(node.children);
ary.push(jsonNode);
}
return ary;
}
DEMO: http://jsfiddle.net/argA3/1/
[
{
"tag": "A",
"title": "test",
"href": "#",
"children": [
{
"tag": "DIV",
"id": "nested-image",
"children": [
{
"tag": "IMG",
"src": "image.jpg"
}
]
}
]
}
]
This seems to work:
function getNestedNodes(nodeList) {
var ary = [];
for (var i = 0; i < nodeList.length; i += 1) {
var attributes = {};
for (var key in nodeList[i].attributes) {
attributes[nodeList[i].attributes.item(key).nodeName] = nodeList[i].attributes.item(key).nodeValue;
}
ary.push({
tag: nodeList[i].nodeName,
attributes: attributes,
children: getNestedNodes(nodeList[i].children)
});
}
return ary;
}
var links = document.querySelectorAll('a');
console.log(JSON.stringify(getNestedNodes(links)));
Output:
[{"tag":"A","attributes":{"href":"#","title":"test"},"children":[{"tag":"DIV","attributes":{"id":"nested-image"},"children":[{"tag":"IMG","attributes":{"src":"https://www.gravatar.com/avatar/d1a336ae4b6876a4c5c044ec17876ce0?s=32&d=identicon&r=PG"},"children":[]}]}]}]
Since we're all prividing various (refactored) bids:
// getNestedNodes2(nodeList)
// #nodeList: a collection of nodes to serialize
function getNestedNodes2(nodeList){
// iterate over the node collection
for (var i = 0, result = []; i < nodeList.length; i++){
// begin building a definition of the current node
var thisNode = {
tag: nodeList[i].tagName
};
// iterate over any attributes on the current node and add them
// to the current definition.
for (var j = 0, attributes = nodeList[i].attributes; j < attributes.length; j++){
thisNode[attributes.item(j).nodeName] = attributes.item(j).nodeValue;
}
// check for child elements and, if present, also add them to
// the definition
if (nodeList[i].childElementCount > 0){
thisNode.children = getNestedNodes2(nodeList[i].children);
}
// add the definition to the results set
result.push(thisNode);
}
// return the results
return result;
}
and the end result:
[
{
"tag": "A",
"title": "test",
"href": "#",
"children": [
{
"tag": "DIV",
"id": "nested-image",
"children": [
{
"tag": "IMG",
"src": "https://www.gravatar.com/avatar/d1a336ae4b6876a4c5c044ec17876ce0?s=32&d=identicon&r=PG"
}
]
}
]
}
]
Keep in mind you're accepting a collection in, which means the nodes in that first call are ignored when you go right in to iterating over them and only building a definition of the children. Instead, work on the nodes within the received collection first, then have recursion take care of the children.

Javascript: Getting all existing keys in a JSON array

I have a JSON array like below:
var jsonArray = [{"k1":"v1"},{"k2":"v2"},{"k3":"v3"},{"k4":"v4"},{"k5":"v5"}]
I don't know which keys does exists in this array.
I want to get all the existing key from the array.
It should be possible something like this:
for(i=0;i<jsonArray.lenght;i++){
// something like- key = jsonArray[i].key
// alert(key);
}
Please tell me the method or way to get all keys existing in Json array.
Regards
Why don't you use a
var jsonObject = {"k1":"v1","k2":"v2","k3":"v3","k4":"v4","k5":"v5"}
instead of your
var jsonArray = [{"k1":"v1"},{"k2":"v2"},{"k3":"v3"},{"k4":"v4"},{"k5":"v5"}]
? Then the solution would be so simple: Object.keys(jsonObject).
Try this:
var L = jsonArray.length;
for (var i = 0; i < L; i++) {
var obj = jsonArray[i];
for (var j in obj) {
alert(j);
}
}
I've also made some modifications of your current code (like length caching).
Loop through the object properties, and select the first "real" one (which given your data schema should be the only real one).
var jsonArray = [{"k1":"v1"},{"k2":"v2"},{"k3":"v3"},{"k4":"v4"},{"k5":"v5"}]
for (var i = 0; i < jsonArray.length; i++) {
for (var prop in jsonArray[i]) {
if (jsonArray[i].hasOwnProperty(prop)) {
var key = prop;
break;
}
}
alert(key);
}
See How to loop through items in a js object? for an explanation of why it's important to use hasOwnProperty here.
Try this:
jsonArray.reduce(function(keys, element){
for (key in element) {
keys.push(key);
}
return keys;
},[]);
This should also work for multiple keys in the array objects.
If you're supporting old browsers that don't have reduce and map, then consider using a shim.
var id = { "object": "page", "entry": [{ "id": "1588811284674233", "time": 1511177084837, "messaging": [{ "sender": { "id": "1393377930761248" }, "recipient": { "id": "1588811284674233" }, "timestamp": 1511177084553, "message": { "mid": "mid.$cAAX_9pLcfu1mCnGmiVf2Sxd2erI2", "seq": 1882, "text": "a" } }] }] };
function getKey(obj, data) {
//#author dvdieukhtn#gmail.com
var data = data || [];
if (obj) {
var keys = Object.keys(obj);
for (var pos in keys) {
console.log();
data.push(keys[pos]);
if ((obj[keys[pos]].constructor === Array)) {
for (var i = 0; i < obj[keys[pos]].length; i++) {
getKey(obj[keys[pos]][i], data);
}
}
else if (obj[keys[pos]].constructor === Object) {
getKey(obj[keys[pos]], data);
}
}
return data;
}
}
console.log(getKey(id));

Is there a more efficent way of selecting a particular object inside an array of objects

Given the following data structure
var things = [{ "name": "thing1", "sex": "male"},
{ "name": "thing2", "sex": "female"}];
I would like to be able to search that array of objects and pull out a particular object.
I currently have the following code written
function selectElementByName (name) {
var returnObject;
for (var i = 0; i < things.length; i++) {
if (things[i].name === name) {
returnObject = things[i];
}
}
if ( returnObject === undefined) {
console.log("Object not found");
}
return returnObject;
}
JsFiddle can be found here
Is there a more efficient way of doing this?
You can make an early exit when an object is found, so that you don't have to loop through the rest of the array:
function selectElementByName(name) {
for (var i = 0; i < things.length; i++) {
if (things[i].name === name) {
return things[i];
}
}
console.log("Object not found");
}
(This will however change the behaviour if there are duplicates, so that it returns the first object found instead of the last.)
If the names are unique, you could use them as key and store the objects in an object instead of in an array:
var things = {
"thing1": { "name": "thing1", "sex": "male"},
"thing2": { "name": "thing2", "sex": "female"}
};
Then you wouldn't need to loop to find an object:
function selectElementByName(name) {
return things[name];
}
If you need the objects in an array, you could still create an index for searching if the array doesn't change so often:
var thingsNameIndex = {};
for (var i = 0; i < things.length; i++) {
thingsNameIndex[things[i].name] = i;
}
Now you can use the index to find the object:
function selectElementByName(name) {
return things[thingsNameIndex[name]];
}
As you have to update or recreate the index as soon as the array changes, this would only be usedful if you do searches in the array much more often than you change the array.
In more recent versions of JavaScript:
var selectElementByName = function(name) {
// This will fetch all items that match the filter
// and place them in a new array
var items = things.filter(function(item) {
return item.name === name;
});
// If there isn't anything in the array, log the error and return.
if (!items.length) {
console.log("Object not found");
return;
}
// Return the first matched element in the array.
return items[0];
};
You can break once it's found at least:
for (var i = 0; i < things.length; i++) {
if (things[i].name === name) {
returnObject = things[i];
break;
}
}

Categories

Resources