Get key values in JSON array - javascript

I'm trying to get the key values of each record in a JSON array when looping through it. Currently I have a simple JSON object like this:
"users": {
"key_11": {
"text": "11"
},
"key_22": {
"text": "22"
},
"key_33": {
"text": "33"
}
}
My current script uses the 'map' method to convert this JSON objet to a loop-able array:
var user_profiles_array = $.map(user_profiles_string, function(el) { return el; });
for (var xt = 0; xt < user_profiles_array.length; xt++) {
console.log(user_profiles_array[xt].text); //11 or 22
}
My question is, how can I get the value for e.g: 'key_11' or 'key_22'?
Thanks!

you can use Object.keys to get an array of all of your object's keys. Once you have that array, you can use Array.forEach to iterate over it as necessary:
Object.keys(usersObject).forEach(function(key, keyIndex) {
console.log("index:",keyIndex,"key:",key,"value:",usersObject[key]);
});
But!
your particular problem here is being caused by using $.map instead of JSON.parse. $.map returns an array, so of course your keys are always going to be numerical array indices - 0, 1, 2, and so on. You're not going to be able to use hash keys to find things in the array returned by $.map. Furthermore, judging by your variable names you're calling $.map on a string which is definitely not going to do what you want. Assuming you figure that part out and you somehow get a valid JavaScript object, and you still need to use $.map() for some reason, what you can do is this:
// $.map will return an array...
$.map(user_profiles_object, function(objVal, objKey) {
// ...and each item in that array will be an object with a
// property named 'key' and a property named 'val'
return {
key: objKey,
val: objVal
};
}).forEach(function(arrayObj) {
// now each item in the array created above will be an object
// created by your callback function:
console.log(arrayObj.key,":",arrayObj.val);
});

You can also rely on Js's foreach.
// JSON string must be valid. Enclose your JSON in '{}' (curly braces);
var user_profiles_string = '{ "users": { "key_11": { "text": "11" }, "key_22": { "text": "22" }, "key_33": { "text": "33" }}}';
var user_profiles_array = JSON.parse(user_profiles_string);
// For retrieval in loop, the Js foreach asigns the key to index param (i in this case).
for (i in user_profiles_array.users) {
// i is the key of the user currently iterated.
console.log('Key name is: ' + i);
// Use i as the index to retrieve array value.
console.log(user_profiles_array.users[i]);
}
// For direct retrieval using any given known key:
console.log(user_profiles_array.users['key_11']);

Related

Delete object items from an array

I have an object element and an array element which contains some items of the object.
I would like to delete the items in the object referenced by the array.
var array = ["test1","test2"];
var object =
...
"test1": {
"na": [
"t",
"t-t",
"t-98",
"t"
]
},
"test2": {
"python": [
"jjj"
]
}
...
When I use
delete object.test1
It works.
However in my case, I want :
for(var i = 0 ; i < array.length ; i++){
delete object.array[i];
}
But I got :
object.array is undefined
Any ideas ?
Fiddle
Use object[array[i]], object.array does not exist
If you are using lodash or underscore you can also use the _.omit function.
object = _.omit( object, array )
You would need to use array object notation.
delete object[array[i]]
Array notation is the only way to retrieve property values if you are indexing using a string value.

Javascript array object arrays

THis is going to sound like a stupid question but here it goes. I have a js array formatted like so
var locationID = [
{ ID: "ID1", location: "location1" },
{ ID: "ID2", location: "location2" },
{ ID: "ID3", location: "location3" },
];
I am trying to loop through the array
for(i = 0; i < locationID.length;i++){
var object = locationID[i];
}
I want to get both elements from the inner array so the ID and location. would I do this by object[0] or object["ID"] for example.
Also is there a more efficient way to do what I need to do like a for each loop or something along those lines.
Use object.ID or object['ID'].
Objects {} in JavaScript are associative, or named arrays. (Also known as a map in many languages. They are indexed by strings (in this case).
Arrays [], are indexed by integral numbers, starting from 0 and counting up to n-1, where n is the length of the array.
If you want to programmatically go through all the (key, value) pairs in each object, you can use this method.
Quotations (String Literals)
To reiterate my comment below about single and double quotes:
If you're talking about inside the [], no [,they're not important]. JavaScript treats single
quotes and double quotes pretty much the same. Both of them denote
string literals. Interestingly, you can use single quotes inside
double quotes or vice-versa: "I wanted to say 'Hello world!'" would be
a (single) valid string, but so would 'But I accidentally said "Goodbye".
This is an optimized loop based from the book of Nicholas Zackas (YAHOO performance chief). I am performing a cached array length to prevent re-evaluation of array length on every iteration of the loop. Please check jsperf.com. Also, native loop is always faster than method based loops jQuery.each and Array.prototype.forEach. This is also supported on browsers below ie8
var currentItem,
locationInfo = [
{ ID: "ID1", location: "location1" },
{ ID: "ID2", location: "location2" },
{ ID: "ID3", location: "location3" },
];
for (var i = 0, len = locationInfo.length; i < len; i++) {
currentItem = locationInfo[i];
console.log(currentItem.ID);//I prefer this because it shrinks down the size of the js file
console.log(currentItem["ID"]);
}
what you have already will return each of the objects in the JSON as you run the loop. What you need is something like
for(i = 0; i < locationID.length;i++){
var object = {locationID[i].ID, locationID[i].location};
}
Remember properties of objects are accessed by their keys since they are key-value pairs.
For loops are going to be your best bet as far as speed, here's how you'd do it with forEach (IE 9+)
locationID.forEach(function(location, i){
console.log(location['ID'])
console.log(location['location'])
});
jQuery make's it a little easier but runs slower
$.each(array, function(i, item){
});
http://jsperf.com/for-vs-foreach/75
Also here a useful link: For-each over an array in JavaScript?
You can use the forEach method, which make your code more cleaner.
See forEach
locationID.forEach(function(elm){
//Here, elm is my current object
var data = elm;
console.log(data.ID):
console.log(data.location);
});
EDIT :
Then for your second question, you should filter and map methods.
function findNamebyID(id){
//Filter by id and map the data to location
return locationID.filter(function(elm){
return elm.ID === id;
}).map(function(elm){
return elm.location;
})
}
Something as:
var location = locationID.reduce(function(ob, cur) {
ob[cur.ID] = cur.location;
return ob;
}, {});
The result you get is:
Object {ID1: "location1", ID2: "location2", ID3: "location3"}
Meaning you can do:
location.ID1 // location1
location.ID2 // location2
...
an alternative to your loop, would be to use the JavaScript for (.. in ..) since you aren't really using the iterator; it just adds fluff
for(i = 0; i < locationID.length;i++){
var object = locationID[i];
}
could be written as:
for (item in locationID) {
var object = item;
}

Iterate through nested JSON tree and change values

What I have is a JSON tree of the following structure:
{
"projects": {
"Proj1": {
"milestones": {
"default": "20150101",
"default2": "20140406",
"default3": "20140101",
"default4": "20131231",
"default5": "20131220"
}
},
"Proj2": {
"milestones": {
"default": "20131231",
"default2": "20131220"
}
}
}
}
I have code to read it into a web page, with the 'default' part in text, and the numbers/dates in a text box/form. The idea is that you can change the dates and submit, which goes to the backend and gets written to a file. All that works for the most part. What I can figure out is how to iterate through the JSON tree I have and write the new values. For example:
Accessing JSONTREE.projects.Proj1.milestones.default returns the value for that key. Setting the value with that call changes the value appropriately. What I want to do is iterate through the entire tree and set the values of the 'defaults' based on whatever is in the form box. I have this:
$.each(formJSON.projects, function (projectName) {
$.each(this, function (selection) {
$.each(this, function (milestones, date) {
var saltKey = projectName + "-" + milestones;
date = document.getElementById(saltKey).value;
});
});
});
but it does nothing, even though 'alert(date)' returns a value. I suspect this is because it's the value, and not a reference to the object, but how can I get to the object? I suspect it's simple, but I'm not a pro with jQuery/JS.
TL;DR How do I get references to a key in a nested JSON tree so I can change the value?
EDIT: Okay, I think this is what I needed: JS/Jquery - using variable in json selector. I changed the 'date' portion to: formJSON.projects[projectName][selection][milestones] = document.getElementById(saltKey).value; which seems to work.
I ran into the same problem and this is my solution to iterate over a JSON object (MongoDB) and modify certain elements regardless of whether these are properties of the object or property is an array with more objects. I know the question is old, but it can be useful to someone.
Assuming we have an object like this or even more complex.
var mixData = {
"Hello": "World",
"Foo" : "Bar",
"sudo": [
{ "apt-get": "upgrade" , "force": false },
{ "apt-get": "update" , "force": true}
],
"colors": ["blue","green"],
"numbers":{
"integer": [
{"num": 1},
{"num": 2},
{"num": 3}
],
"operator": "addition"
}
};
And we want to replace some string (blue in this case), but we don't know where is or what kind of constructor has our data.
// Detect if the element is an Array
function isElementArray(element){
return (element.constructor === Array ? true : false);
}
//Detect if the element is an Object
function isElementObject(element){
return (element.constructor === Object ? true : false);
}
Now that we have these two functions, we use a third to iterate over the item, regardless of whether an object or array.
function iterate(element){
//Check if the element is an Object
if(isElementObject(element)){
for (var property in element){
if(isElementObject(element[property])){
element[property] = iterate(element[property]);
}else if(isElementArray(element[property])){
//An array
for(var x = 0; x < element[property].length; x++){
element[property][x] = iterate(element[property][x]);
}
}else{
if(element.hasOwnProperty(property)){
console.log("New object inside object property");
element[property] = iterate(element[property]);
}else{
element[property] = replaceElement(element[property].toString());
console.log("Single Element: " + element[property] )
console.log(element + " " + element[property]);
}
}
}
}else if(isElementArray(element)){
//An Array
for (var x = 0; x < element.length; x++){
element[x] = iterate(element[x]);
}
}else{
//Single element in array or property
element = replaceElement(element.toString());
console.log("Single Element : " + element);
}
return element;
}
And the function we need to use to replace our string.
function replaceElement(element){
if(element === "blue"){
return "Blue is the warmest color"
}else{
return element;
}
}
And finally, we can get the result:
console.log(iterate(mixData));
The result is:
{
"Hello": "World",
"Foo" : "Bar",
"sudo": [
{ "apt-get": "upgrade" , "force": false },
{ "apt-get": "update" , "force": true}
],
"colors": ["Blue is the warmest color","green"],
"numbers":{
"integer": [
{"num": 1},
{"num": 2},
{"num": 3}
],
"operator": "addition"
}
};
You can change the replace function to suit your needs. And of course, remove al the console logs.
Your editing the passed value and not the original JSON object.
One way to fix this is to create a new JSON object, build as you iterate through the existing one, and then overwrite the original or use the new JSON object.
Another is to create a var holding the original JSON object and either pass it through your functions or access it directly inside the functions.

Trouble Sorting JSON

I have a JSON object like the following:
{"Data": {
"290": {
...
}
"300": {
...
}
"281": {
...
}
}
}
How would I sort this JSON based on the top container keys (i.e. "290", "300", "281")?
Edit: So I used
$.getJSON('current/csf.txt', function(data) { arr = data["Data"]; }
And it sorted them based on the key. Why did this happen?
You've tagged this "JavaScript" so I assume you mean "A JavaScript object generated from this JSON".
In which case:
Loop over the property names (with a for in loop).
Use them to populate an array.
Sort the array.
Use the array as a map.
(You can't store ordered data in an object).
If you want to store the results in JSON, then you will need to change your data structure (and use an array (of objects)). Objects are explicitly unordered.
Your structure is wrong, it should be something like:
{
"Data": [
{
"id": "290"
},
{
"id": "300"
},
{
"id": "282"
}
]
}
Objects are for unordered data. Use arrays for ordered data. And the array is really easy to sort here:
obj.Data.sort(function(a,b){
return a.id - b.id;
});
You can convert to this structure like so:
function copyProps(dest, src) {
for (var key in src) {
dest[key] = src[key];
}
return dest;
}
var newData = [];
for (var key in obj.Data) {
newData.push(copyProps({
id: key
}, obj.Data[key]));
}
I agree with Amberlamps comment, you shouldn't be trying to sort the keys of an object, but if you wanted to for some reason you might take a look at underscore.js's sortBy method
Even if you COULD sort object attributes, there's no guarantee that you could read them back in sorted order. In Javascript, object attributes are not stored in a specific order; an object simply has attributes.
You cannot use array index notation to access object attributes, so the notion of sorting object attributes by key is moot.

JQuery Array To Re-arranged JSON object

I want to covert this javascript Array
[
"Data",
[
"API",
"Apiales",
"Apiaceae",
"Apia",
]
]
to this rearranged json Format
[
{"name":"API","id":"1"},
{"name":"Apiales","id":"1"},
{"name":"Apiaceae","id":"1"},
{"name":"Apia","id":"1"}
]
Thanks
update:
i have tried this
var aNewData =[];
for(i in aData[1]){
var item={};
item.name = aData[1][i];
item.id = "1";
aNewData[i]=item;
}
Where do the ids come from? Test following script, your array is in aData and the result will be in aNewData:
var aNewData = [];
for (var i = 0; i < aData[1].length; i++) {
aNewData.push({
"name": aData[1][i],
"id": 20 + i
});
}
Also see this example.
You might easily transform those data via folding:
var sourceData = ["API","Apiales","Apiaceae","Apia"];
var transformed = sourceData.reduce(function(result, name, index) {
return result.concat({
name: name,
id: 20 + index
});
}, []);
This will give you essentially the same, as the for loop of scessor, but in a more data-centric way.
Think of it like this:
You hold your source data (the array with all those "api*" strings)
You create a fresh resulting array [] (passed as 2nd argument to the reduce), which should be returned as your next result.
Pass an unnamed function to reduce that will be called with 3 arguments, each time it is called, namely result, which is you recently created array, name the value of each of those "api*" strings, and index, which is the index of those strings within the original array.
You look at each of those "api*" strings consecutively and put a new object containing your desired data into it. As result.concat will return the whole array, you just add those
The result array containing all your data will be returned.
But just in case you wanted to be backward compatible with older browsers, I'd recommend using underscore.js for that.

Categories

Resources