I have a json object array. I want to search the array and for each object, create a list of 'services' that is a comma-seperated list of all the keys which have a value of "yes".
The list of json objects with the services list is then displayed in html using jquery's each.
Its a large json file so I want to do it as efficiently as possible.
I already have the object's properties being accessed through jQuery's each (ie, obj.name)
-- so I think it should be possible to filter the services listed for each object using
jQuery's filter, and then display the key if the value is yes.
But it seems like a more efficient option would probably be to create a new javascript array, join the services with a value of yes and then add that variable to the html being
appended.
Im not sure which would be faster and so far havent been very successful at either... so any advice and examples would be very helpful.
Here's what the json array looks like:
[
{"name":"name1",
"service1":"y",
"service2":"y",
"service3":"n",
},
{"name":"name2",
"service1":"n",
"service2":"y",
"service3":"n",
},
];
If you just want to filter the array then use grep.
grep - Finds the elements of an array which satisfy a filter function. The original array is not affected.
http://api.jquery.com/jQuery.grep/
First off, delete trailing commas. Internet Explorer gets really, really confused by them. Anyway, I assume you don't want to "search" the array when you say "for each value"; you want to iterate through the array and parse it into a more usable list. The first method I'd suggest is just passing what you want as the array you desire, but if that's not an option, what you're looking for is some variant of this, which should be fairly efficient (jsFiddle example):
var json = [
{"name":"name1", "service1":"y", "service2":"y", "service3":"n"},
{"name":"name2", "service1":"n", "service2":"y", "service3":"n"}
];
var parsed = {};
for (var i = 0, iLen = json.length; i < iLen; i++) {
// Assuming all we need are the name and a list
var name;
var list = [];
for (var key in json[i]) {
var value = json[i][key];
// We need to hold on to the name or any services with value "y"
if (key === "name") {
name = value;
} else if (value === "y") {
list.push(key);
}
}
// Add them to the parsed array however you'd like
// I'm assuming you want to just list them in plain text
parsed[name] = list.join(", ");
}
// List them on the web page
for (var key in parsed) {
document.write(key + ": " + parsed[key] + "<br>");
}
That way you wind up with a display to the visitor of the services available and still keep an array around for further use if necessary.
jQuery.inArray() Search for a specified value within an array and return its index (or -1 if not found).
http://api.jquery.com/jQuery.inArray/
Or
http://api.jquery.com/jQuery.each/
Related
This is the array:
{"C8_235550":
{"listing":"aut,C8_235550_220144650654"},
"C8_231252":
{"listing":"aut,C8_231252_220144650654"}}
It was fetched with a GET request from a Firebase database using Google Apps Script.
var optList = {"method" : "get"};
var rsltList = UrlFetchApp.fetch("https://dbName.firebaseio.com/KeyName/.json", optList );
var varUrList = rsltList.getContentText();
Notice the .getContentText() method.
I'm assuming that the array is now just a string of characters? I don't know.
When I loop over the returned data, every single character is getting pushed, and the JavaScript code will not find key/value pairs.
This is the FOR LOOP:
dataObj = The Array Shown At Top of Post;
var val = dataObj;
var out = [];
var someObject = val[0];
for (var i in someObject) {
if (someObject.hasOwnProperty(i)) {
out.push(someObject[i]);
};
};
The output from the for loop looks like this:
{,",C,8,_,2,3,5,5,5,0,",:,{,",l,i,s,t,i,n,g,",:,",a,u,t,,,C,8,_,2,3,5,5,5,0,_,2,2,0,1,4,4,6,5,0,6,5,4,",},,,",C,8,_,2,3,1,2,5,2,",:,{,",l,i,s,t,i,n,g,",:,",a,u,t,,,C,8,_,2,3,1,2,5,2,_,2,2,0,1,4,4,6,5,0,6,5,4,",},}
I'm wondering if the array got converted to a string, and is no longer recognized as an array, but just a string of characters. But I don't know enough about this to know what is going on. How do I get the value out for the key named listing?
Is this now just a string rather than an array? Do I need to convert it back to something else? JSON? I've tried using different JavaScript array methods on the array, and nothing seems to return what it should if the data was an array.
here is a way to get the elements out of your json string
as stated in the other answers, you should make it an obect again and get its keys and values.
function demo(){
var string='{"C8_235550":{"listing":"aut,C8_235550_220144650654"},"C8_231252":{"listing":"aut,C8_231252_220144650654"}}';
var ob = JSON.parse(string);
for(var propertyName in ob) {
Logger.log('first level key = '+propertyName);
Logger.log('fisrt level values = '+JSON.stringify(ob[propertyName]));
for(var subPropertyName in ob[propertyName]){
Logger.log('second level values = '+ob[propertyName][subPropertyName]);
}
}
}
What you have is an object, not an array. What you need to do is, use the
Object.keys()
method and obtain a list of keys which is the field names in that object. Then you could use a simple for loop to iterate over the keys and do whatever you need to do.
I am trying to create number of arrays like _temp0[],_temp1[],_temp2[] so on and I want to store values of data[] in it.
so value of data[0] goes in array_temp0[] after splitting,
data[1] goes in _temp1[] and so on
to elaborate more-
If value of data[0] is string a,b,c
then array _temp0[] should be
_temp0[0]=a
_temp0[1]=b
_temp0[2]=c
I wrote this function
for(var k=0;k<data.length-1;k++)
{
window['_temp' + k] = new Array();
alert("actual data -- >"+data[k]);
'_temp'+k= data[k].split(',');
alert("data after split -- >"_temp[k]);
}
but it is not working, how do I solve it?
You can do the same using javascript objects. Here is an example of how to do it.
Create an object of name '_temp':
var _temp = {};
When you iterate through 'data' variable then, you can dynamically add attributes to it,say _temp['data0'], _temp['data1'] etc, and every attribute will be an array. For that, you need to write something like:
for(var k=0;k<data.length-1;k++)
{
_temp['data'+k] = data[k].split(',');
}
This will not create the variables identical to what you want. However, this is similar to what you want.
used
window['_temp'+k]= data[k].split(',');
instead of
'_temp'+k= data[k].split(',');
and it worked, thanks to go-oleg
In JS localStorage I can use
localStorage.getItem(key);
to get the value of the entry corresponding to the key in the key variable.
How can I get the entry's ID (instead of value) using the key?
Edit: sorry I must have confused people. What I mean by "key" is the numerical key - which is 0, 1, 2, 3 etc depending on how many items have been saved. Then I want to find out the ID it was stored as, eg foo in the below example, from the numerical key.
localStorage.setItem('foo', 'bar');
LocalStorage is implemented as a key-value pair ( see for instance: https://developers.google.com/web-toolkit/doc/latest/DevGuideHtml5Storage ) - so you don't have an id like an unique auto-incremented id in a database table.
However, you can access the elements using an index - to get the index of a key in localStorage, the only way I can find is to loop through each key until you find the one you are searching for, like this:
var findIndexOfKey = function(searchKey) {
for (var i = 0; i < localStorage.length; i++){
var key = localStorage.key(i);
if(key === searchKey)
return i;
}
return -1;
}
And then, to retrieve the key using the index, you can do:
localStorage.key(myIndex);
And to retrieve the value, you can do this:
localStorage.getItem(localStorage.key(myIndex));
... or this ( which would be equivalent to localStorage.getItem("myKey")):
localStorage.getItem(localStorage.key(findIndexOfKey("myKey")));
when setting the item you should give it's ID as a value and than when you call getItem(key) it should give it's ID as a return ex:
localStorage.setItem('foo', 'bar');
localStorage.getItem('foo'); // it should return the bar
take a look for this examples it may help : http://mathiasbynens.be/notes/localstorage-pattern
The answer:
localStorage.key(key);
Sorry, I realise I've got confused between what's actually called the key, which I called the ID, and it's numerical ID which I called the key...
I don't think it is possible. Can't you just make localStorage.setItem(yourkey,value)? I mean
localStorage.setItem(0,value)
localStorage.setItem(1,value)
This may be useful in loops for example.
As per what I know, arrays in Javascript is nothing but the combination of methods and objects.
Now my task is to display the values of array (say y_array)
I have used for(x in y_array) and then displayed the value.
In mozilla and in IE its working fine, but in IE it displays the first element of array with index as indexOf and value is indexOf(obj, from) which i dont want.
I tried
if(x!='indexOf') { display the array value ; }
It worked and things were fine but there is extensive use of arrays been displayed and I am looking for some permanent fix rather than this hardcoded one.
Can anyone please help me?
You are not the first mixing up arrays and objects. SO should contain a FAQ for this kind of questions ;)
Let's try to explain things:
An array is a row of values, which can be retrieved using their position in the row. The order of the array values is fixed (and may be reordered).
An object is a variable that contains named properties in the form of key-value pairs. The order of the key-value pairs belonging to an object is arbitrary.
An array looks like: [ 'first', 'second', 'third', ..., 'nth' ]
An object looks like: { first:'firstvalue', second:'secondvalue', ..., nth:'nthvalue' }
The first element of an array is the element with index 0 (so the first position in the row has index value 0). You retrieve it using myArray[0]
An object is unordered, so it has no first element. You retrieve any element from it using myObject.somekey or myObject['somekey'].
For arrays you use a loop iterating through the numbered index until the end of the array is reached:
var i=0, len = myArray.length;
for ( i; i<len; i++ ) {
//do something with >>> myArray[i] <<<
}
For objects you use a loop using the key and the in operator (making sure you are only retrieving user defined properties of the object with the .hasOwnAttribute method):
for ( var key in myObject ){
if (myObject.hasOwnProperty(key)) {
// do something with >>> myObject[key] <<<
}
}
Basically, think of an array as a cupboard with drawers, each containing a value. An object can be imagined as a pile of boxes with stickers on the lid, describing the content of the box. Retrieving something from an object, you ask: is there a box with sticker y in pile x and if so, what's in it? Retrieving something from an array, you ask: please give me the contents of drawer nr x.
Now as to your question: the array you are retrieving values for with a for..in loop contains a user defined method, namely indexOf. Using the object style loop for it, the array is treated as object, and the indexOf key (with value like function(){...} I bet) is shown too. IE That's why it may be better to use a traditional for loop with a numeric index when iterating over arrays.
Why is this only in IE? In modern browsers indexOf is a native method of the Array prototype, and native methods are not shown (unless you loop through their prototype that is). IE < 9 doesn't have a native indexOf method for arrays. Somewhere in the scripting you use the method has been added to the Array prototype as a user defined extension.
Bottom line for your problem: don't use for ... in to loop through the values of an array.
For arrays you should use this for loop:
var y_array = [1,2,3,4];
for (var i = 0; i < y_array.length; i++) {
var value = y_array[i];
// do what you want
alert(i + ': ' + value);
}
For objects (objects are like associative arrays - property: value) use this loop:
var y_array = { prop_1 : "value a", prop_2: "value_2", prop_3: 333 }
for (var key in y_array) {
var value = y_array[key];
// do what you want
alert(key + ': ' + value);
}
if there is no value in your json Object like jsobObj = {}. Then you got the indexOf prototype function in side the empty object in IE < 9. (with value like function(){...} I bet) is shown too.
Your can check a condition in side your for Loop. and skip that indexOf.
if(key =='indexOf'){continue;}
E.g :
var jsonObj = { key_1 : "value a", key_2: "value_2", key_3: 333 }
for (var key in y_array) {
if(key == 'indexOf'){continue;} // check if the array contain indexOf
var value = y_array[key];
// do what you want
alert(key + ': ' + value);
}
is there any way I can get the return of $.getJSON into a variable array?
I know its async and out of scope, but I will use it inside ajax callback, I just need to get all the values first and check them against another array.
Something like:
$.getJSON('itemManager.php?a=getItems', function(data){
// itemArray = new Array(data);
// idsArray = new Array(data.id);
for (var i in someOtherArray){
if($.inArray(i, idsArray) == -1){
// do something...
// get jason variable by id?
// itemArray[i].someVariable
}
}
}
EDIT: JSON structure
[{"id":"786","user_id":"1","seller_id":"2","address_id":"1","time":1299852115,"publicComment":null,"personalComment":null},
{"id":"787","user_id":"1","seller_id":"2","address_id":"1","time":1299852115,"publicComment":null,"personalComment":null},
{"id":"785","user_id":"1","seller_id":"2","address_id":"1","time":1299852114,"publicComment":null,"personalComment":null},
{"id":"784","user_id":"1","seller_id":"2","address_id":"1","time":1299852113,"publicComment":null,"personalComment":null},
{"id":"783","user_id":"1","seller_id":"2","address_id":"1","time":1299852111,"publicComment":null,"personalComment":null}]
This is basically the idea.
Get all the values
Isolate the id values of JSON objects
Loop another array
Check if json id is inside the other array
Access other json variables by id value
There are various solutions here I guess, but I'm looking for something with minimal code.
With the given information, there is not shortcut to test the existence of IDs. You really have to loop over everything. However you can improve a bit by creating an id => object mapping:
$.getJSON('itemManager.php?a=getItems', function(data){
var items = {};
for(var i = data.length; i--; ) {
items[data[i].id] = data[i];
}
for (var j = someOtherArray.length; j--; ){
var item = items[someOtherArray[j]];
if(item){
// do something with `item`
}
}
}
It woud be even better if you create this structure on the server already, then it would be:
$.getJSON('itemManager.php?a=getItems', function(data){
for (var j = someOtherArray.length; j--; ){
var item = data[someOtherArray[j]];
if(item){
// do something with `item`
}
}
}
You should also consider which arrays will contain more elements, data or someOtherArray and adjust your data structures such that you loop over the smaller array only.
Update:
To create the appropriate structure on the server with PHP, you have to create an associate array.
So at the point where you add an object to the array, you should not do
$items[] = $obj;
but
$items[$obj->id] = $obj; // or $obj['id'] if you have an array
If you get an array as your JSON response then your data variable in your callback is an array, no need to do anything with it.
If you get an object as your JSON response as the data.id in you example might suggest, and some of it's values is an array, then just use data.id as an array, or use var array = data.id; if that is more convenient for you.
Remember that data in your callback is just whatever you got as JSON. It can be an object (which is an associative array), an array, a string, a number, or a true, false or null value. If it is an object you access it using data.key, if it is an array you access it using data[index]. I say it because I suspect that you might be confusing arrays with objects here.