How do I access the nested keys in this nested javascript object? - javascript

I have the following javascript object:
result = {
"banking6dig":{
"GM-B-001":{
"releaseDate":"2/2/2012 14:44","noOfHex":"3","versInfo":"6 digit Banking"
},
"GM-B-002":{
"releaseDate":"1/2/2012 14:46","noOfHex":"3","versInfo":"6 digit Banking with changes"
}
},
"paynpark":[]
}
Explanation:
"banking6dig" and "paynpark" are applications
"banking6dig" has two subversions : "GM-B-001" and "GM-B-002"
"paynpark" has no subversions.
Additionally, each subversion has its own properties,viz, "releaseDate", "noOfHex", and "versInfo".
This object "result" is built after a php request, so it can have any number of apps and subversions; the format, however is ALWAYS the same.
I have tried this on jsFiddle: http://jsfiddle.net/2JLtZ/1/
How do I find out the number of "subversions" in each "app"? (I get some 40 "subversions"!)
How do I add an app to the object "result", e.g., "electricity" with its properties reset?
How do I add a subversion to "paynpark", e.g. "fixedRate"?
How do I modify a subversions properties, for example change "releaseDate" of "GM-B-001" to "3/12/2012 14:46"?

1.
var i=0;
for (var j in result['banking6dig']) i++;
alert('banking6dig has '+i+' subversions'):
2.
result.electricity={}
3.
paynpark.fixedRate={};
Thanks AlienWebguy for pointing this out.
4.
result['banking6dig']["GM-B-001"]["releaseDate"]="3/12/2012 14:46";

result = {"banking6dig":{"GM-B-001":{"releaseDate":"2/2/2012 14:44","noOfHex":"3","versInfo":"6 digit Banking"},"GM-B-002":{"releaseDate":"1/2/2012 14:46","noOfHex":"3","versInfo":"6 digit Banking with changes"}},"paynpark":[]};
var app = [],
svn = {};
for (var _app in result) {
if(result.hasOwnProperty(_app)){
app.push(_app);
svn[_app] = [];
for (var _svn in result[_app]){
if(result[_app].hasOwnProperty(_svn)){
svn[_app].push(_svn);
}
}
}
}
// How man apps?
alert(app.length);
// How many subversions?
alert(svn['banking6dig'].length);
// Add an app 'electricity'
result.electricity = {};
// Add subversion to paynpark
result.paynpark.fixedRate = {}
// Add electricity
result.electricity = {};
app.push('electricity');
// Modify subversion
result.banking6dig['GM-B-001'].releaseDate = '3/12/2012';
console.log(result);
Demo: http://jsfiddle.net/AlienWebguy/DpCTP/

Related

Object of Names / split into separate objects or arrays

I am looking for some general advice about how I should be thinking to go about doing this.
What I need to do is take an object that has "usernames" : userId, etc.. and split them into separate objects or arrays with each object only containing usernames that start from a certain letter.
So right now I have:
allusers = {"adam292":10302, "alex92":12902, "briannv999":10302, "sandra127":11102, "sam11":100 }
but I need to split them into their own objects or arrays like the following:
ausers = { "adam292":10302, "alex92":12902 }
busers = { "briannv999":10302 }
susers = {"sandra127":11102, "sam11":1002 }
I am doing this because I need to display a dialog box that also shows the letters a - z which would be links that you can click to display users that start with that letter.
Any advice is very much appreciated!
Here is one way to do it:
Working Fiddle
looping through the object we grab the first letter and check to see if we have a key for it in our users object, if not we make one and assign an array (containing the user data) to it, if yes we push to that array:
var users = {};
for (var user in allusers) {
var firstLetter = user.slice(0,1);
if (users[firstLetter]) {
users[firstLetter].push([user, allusers[user]]);
}
else {
users[firstLetter] = [[user, allusers[user]]];
}
}
The output of the code above using your example object is the following:
{
a: [["adam292", 10302], ["alex92", 12902]],
b: [["briannv999", 10302]],
s: [["sandra127", 11102], ["sam11", 100]]
}
you can do this in a loop:
letter2users = {}
for (var uname in allusers) {
if (!letter2users[uname[0]]) {
letter2users[uname[0]] = [];
}
letter2users[uname[0]].push(allusers[uname]);
}
# access this by using letter2users.a lettersusers.b

Two javascript arrays, using a key to look up

I have two data structures (they are much longer, these are just excerpts)
var data = [
{count: 6, zip: "78705"},
{count: 4, zip: "78754"},
{count: 33, zip: "78757"}
]
var txcodes = [
{county: "SWISHER", code: "437"},
{county: "TARRANT", code: "439"},
{county: "TAYLOR", code: "441"},
{county: "TRAVIS", code: "453"}
]
I have written code that successfully goes through “data” and takes the zipcode and retrieves the corresponding county (from an external website via HTTP request). It returns a structure that looks like
results = {
TRAVIS: 8,
TAYLOR: 1
}
(8 and 1 are examples of counters for how many times a zipcode from data occurs…basically a running count).
What I need to do next is use the keys from results to look up what the corresponding code in txcodes is. How do I do this?
var currentCounty = str.result[0].County
returns the county from results.
console.log(txcodes[i].county + " " + txcodes[i].code)
prints the county & code from txcodes.
I’m a little confused on how to do this. It seems like a relatively simple concept but I can’t seem to get the desired result. Can someone please point me in the right direction?
If county names are unique and if you are going to be making repeated lookups, you should build a "map" of the codes out of the array:
var txcodesByCounty = txcodes.reduce(function(p, c) {
p[c.county] = c.code;
return p;
}, {});
You can then look up codes directly from this map.
Build a lookup map like this :
var lookupMap = {};
for (var i = 0; i < txcodes.length; i++) {
var element = txcodes[i];
lookupMap[element.county] = element;
}
Then you can simply do this to print the desired output :
console.log(lookupMap[currentCounty].county + " " + lookupMap[currentCounty].code);
If the county in your result is only available as a key, you'll need to for..in, Object.keys or Object.getOwnPropertyNames to access them.
After, access the details via a map as others have suggested
var county, found = [];
for (county in results)
found.push(map[county]);
So what you get back from your HTTP request is a simple object, and you need to access its property names. You can do that easily with Object.keys:
resultKeys = Object.keys(result);
This will give you an array of the object properties:
[ "TRAVIS", "TAYLOR" ]
You can easily iterate over this array now, and inside you ask your result object for its value:
for (var i = 0; i < resultKeys.length; i++) {
console.log(resultkeys[i] + ": " + result[resultkeys[i]]);
}
Using this technique, you can use for example underscore.js libary to easily filter for your desired data:
for (var i = 0; i < resultKeys.length; i++) {
console.log(_.filter(txcodes , function(key){ return txcodes.county== resultkeys[i]; }));
}

HTML5 Local Storage with saved integers and variables

I'm trying to achieve a function that makes the user able to save a mathematical formula that uses static variables that I've already created and save them with Local Storage.
Then the script fetches that formula from the Local Storage, does the math and displays the results on a table.
I have everything in order, except the fetching part;
as localStorage.getItem() returns a string, and converting it with parseFloat()/parseInt() only returns the first integer or NaN.
Both of this messes up the expected the results.
Is there any way I can get Objects from localStoage that contains both integers and variables?
Heres an example of a formula that should work, fetched by 5 localStorage.getItem() requests.
avgFrags*250
avgDmg*(10/(avgTier+2))*(0.23+2*avgTier/100)
avgSpots*150
log(avgCap+1,1.732)*150
avgDef*150
Any ideas or alternatives?
EDIT:
Each line represents the output of a getItem() request;
form_frag = localStorage.getItem('formula_frag');
form_dmg = localStorage.getItem('formula_dmg');
form_spot = localStorage.getItem('formula_spot');
form_cap = localStorage.getItem('formula_cap');
form_def = localStorage.getItem('formula_def');
localStorage store in a key-value store where every value is pushed to a string. If you are certent that you are handling "integers" you can push the string to a number:
var avgFrags = +localStorage.getItem('avgFrags'); // The + infront pushes the string to number.
I'm not completely sure that I understand your question.
(+"123") === 123
You can convert easily convert your strings to functions if you know the variable names before hand using Function(). The first parameter(s) are your function arguments and the last is your function body.
var func1 = Function('avgFrags', 'return avgFrags * 250;');
This is equivalent to:
function func1(avgFrags) {
return avgFrags * 250;
}
Known Function Signature
If you know what variable names will be used for each item in local storage then it should be easy for you to do what you want with function:
// from your edited question
form_frag = localStorage.getItem('formula_frag');
form_dmg = localStorage.getItem('formula_dmg');
// ... create functions
var fragsFunc = Function('avgFrags', form_frg );
var dmgFunc = Function('avgDmg', 'avgTier', form_dmg );
// ... get frags
var frags = fragsFunc (10); // frags = 2500; // if sample in storage
Unknown Function Signature
Now if you have a limited amount of variable names and you don't know which ones will be used with each function then you can do something like:
var avgFrags, avgDamage, avgTier, avgSpots, avgCap, avgDef;
// ... get from storage
form_frag = localStorage.getItem('formula_frag');
form_dmg = localStorage.getItem('formula_dmg');
// ... create functions
var fragsFunc = Function('avgFrags', 'avgDamage', 'avgTier', 'avgSpots', 'avgCap', 'avgDef', form_frag);
var dmgFunc = Function('avgFrags', 'avgDamage', 'avgTier', 'avgSpots', 'avgCap', 'avgDef', form_frag);
// ... get frags, only the first argument is used, but we don't know that.
var frags = fragsFunc (avgFrags, avgDamage, avgTier, avgSpots, avgCap, avgDef); // frags = 2500; // if sample in storage
You can make this simpler by having just one variable passed into the function which is an object that holds all of the arguments that can be passed to the function. Just have to make sure that the function writer uses that object.
var settings = {
avgFrags: 10,
avgDamage: 50,
// ...
};
var fragsFunc = Function('s', 's.avgFrags * 250');
var frags = fragsFunc (settings);
Getting parts with an regex
I am assuming that the above will get the job done, that you don't really want an object with variable names and numbers and operators.
If you just need the variable names and numbers (and operators) you can use a regex for that.
([a-z_$][\w\d]*)|([0-9]*\.?[0-9]+)|([^\w\d\s])
You can use that to create an array with each part. Also each part is grouped so you know which is a variable name, which is a number, and which is an other (parenthesis or operator)
var re = /(\w[\w\d]*)|([0-9]*\.?[0-9]+)|([^\w\d\s])/g,
match,
results;
while ((match = re.exec(localStorage.getItem('formula_frag'))) {
results.push({
text: match[0],
type: (match[1]) ? 'var' | (match[2]) ? 'number' : 'other'
})
}
You can view the output of the regex with your sample data using REY.
Yes you can set Objects in localstorage
Here is the fiddle for that - http://jsfiddle.net/sahilbatla/2z0dq6o3/
Storage.prototype.setObject = function(key, value) {
this.setItem(key, JSON.stringify(value));
}
Storage.prototype.getObject = function(key) {
var value = this.getItem(key);
return value && JSON.parse(value);
}
$(function() {
localStorage.setObject('x', {1: 2, 2: "s"})
console.log(localStorage.getObject('x'));
});

Hash Tables in javascript

I am trying to build a data structure.
In my limited knowledge, 'hash table' seems to be the way to go. If you think there is an easier way, please suggest it.
I have two, 1-dimensional arrays:-
A[] - contains names of badges (accomplishment)
B[] - contains respective dates those achievements were accomplished from array A[].
An achievement/accomplishment/badge can be accomplished more than one time.
Therefore a sample of the two arrays:-
A['scholar', 'contributor', 'teacher', 'student', 'tumbleweed', 'scholar'.....,'scholar',......]
B['1/2010', '2/2011', '3/2011', '6/2012', '10/2012', '2/2013',......'3/2013',........]
What I want to achieve with my data structure is:-
A list of unique keys (eq:- 'scholar') and all of its existing values (dates in array B[]).
Therefore my final result should be like:-
({'scholar': '1/2010', '2/2013', '3/2013'}), ({'contributor' : ........})..........
This way I can pick out a unique key and then traverse through all its unique values and then use them to plot on x-y grid. (y axis labels being unique badge names, and x axis being dates, sort of a timeline.)
Can anyone guide me how to build such a data structure??
and how do I access the keys from the data structure created.... granted that I don't know how many keys there are and what are their individual values. Assigning of these keys are dynamic, so the number and their names vary.
Your final object structure would look like this:
{
'scholar': [],
'contributor': []
}
To build this, iterate through the names array and build the final result as you go: if the final result contains the key, push the corresponding date on to its value otherwise set a new key to an array containing its corresponding date.
something like:
var resultVal = {};
for(var i = 0; i < names.length; ++i) {
if(resultVal[names[i]]) {
resultVal[names[i]].push(dates[i]);
} else {
resultVal[names[i]] = [dates[i]];
}
}
Accessing the result - iterating through all values:
for(var key in resultVal) {
var dates = resultVal[key];
for(var i = 0; i < dates.length; ++i) {
// you logic here for each date
console.log("resultVal[" + key + "] ==> " + resultVal[key][i]);
}
}
will give results like:
resultVal[scholar] ==> 1/2010
resultVal[scholar] ==> 2/2013
resultVal[scholar] ==> 3/2013
resultVal[contributor] ==> 2/2011
resultVal[teacher] ==> 3/2011
resultVal[student] ==> 6/2012
resultVal[tumbleweed] ==> 10/2012
You can try this...
var A = ['scholar', 'contributor',
'teacher', 'student', 'tumbleweed', 'scholar','scholar'];
var B = ['1/2010', '2/2011',
'3/2011', '6/2012', '10/2012', '2/2013','3/2013'];
var combined = {};
for(var i=0;i<A.length;i++) {
if(combined[A[i]] === undefined) {
combined[A[i]] = [];
}
combined[A[i]].push(B[i]);
}
Then each one of the arrays in combined can be accessed via
combined.scholar[0]
or
combined['scholar'][0]
Note the === when comparing against undefined

Looping to Parse JSON Data

Description and Goal:
Essentially data is constantly generated every 2 minutes into JSON data. What I need to do is retrieve the information from the supplied JSON data. The data will changed constantly. Once the information is parsed it needs to be captured into variables that can be used in other functions.
What I am stuck in is trying to figure out how to create a function with a loop that reassigns all of the data to stored variables that can later be used in functions.
Example information:
var json = {"data":
{"shop":[
{
"carID":"7",
"Garage":"7",
"Mechanic":"Michael Jamison",
"notificationsType":"repair",
"notificationsDesc":"Blown Head gasket and two rail mounts",
"notificationsDate":07/22/2011,
"notificationsTime":"00:02:18"
},
{
"CarID":"8",
"Garage":"7",
"Mechanic":"Tom Bennett",
"notificationsType":"event",
"notifications":"blown engine, 2 tires, and safety inspection",
"notificationsDate":"16 April 2008",
"notificationsTime":"08:26:24"
}
]
}};
function GetInformationToReassign(){
var i;
for(i=0; i<json.data.shop.length; i++)
{
//Then the data is looped, stored into multi-dimensional arrays that can be indexed.
}
}
So the ending result needs to be like this:
shop[0]={7,7,"Michael Jamison",repair,"Blown Head gasket and two rail mounts", 07/22/2011,00:02:18 }
shop[1]={}
You can loop through your JSON string using the following code,
var JSONstring=[{"key1":"value1","key2":"value2"},{"key3":"value3"}];
for(var i=0;i<JSONstring.length;i++){
var obj = JSONstring[i];
for(var key in obj){
var attrName = key;
var attrValue = obj[key];
//based on the result create as you need
}
}
Hope this helps...
It sounds to me like you want to extract the data in the "shop" property of the JSON object so that you can easily reference all of the shop's items. Here is an example:
var json =
{
"data":
{"shop":
[
{"itemName":"car", "price":30000},
{"itemName":"wheel", "price":500}
]
}
},
inventory = [];
// Map the shop's inventory to our inventory array.
for (var i = 0, j = json.data.shop.length; i < j; i += 1) {
inventory[i] = json.data.shop[i];
}
// Example of using our inventory array
console.log( inventory[0].itemName + " has a price of $" + inventory[0].price);
Well, your output example is not possible. You have what is a list of things, but you're using object syntax.
What would instead make sense if you really want those items in a list format instead of key-value pairs would be this:
shop[0]=[7,7,"Michael Jamison",repair,"Blown Head gasket and two rail mounts", 07/22/2011,00:02:18]
For looping through properties in an object you can use something like this:
var properties = Array();
for (var propertyName in theObject) {
// Check if it’s NOT a function
if (!(theObject[propertyName] instanceof Function)) {
properties.push(propertyName);
}
}
Honestly though, I'm not really sure why you'd want to put it in a different format. The json data already is about as good as it gets, you can do shop[0]["carID"] to get the data in that field.

Categories