I have an object (returned from jQuery ajax) that looks like this:
data:{
materials:{
1:{
id:1,
name:"jacob"
}//1 (some integer)
}//materials
}//data
I'm trying to access name, but I can't get passed the object 1. I tried using makeArray() like this
var m = $.makeArray(data.materials);
var m0 = m.shift();
console.log(m);
console.log(m0);
$isArray(m) & $.isArray(m0) return true, but m and m0 both return:
1:{
id:1,
name:"jacob"
}//1 (some integer)
I expect that shift() to return the object that's inside of 1.
When I try to access m0.name it returns undefined, and when I try to access m[1] it returns undefined.
btw data.materials["1"].name works. the problem is 1 is variable (I don't know what it will be, so I wanted to use shift() which doesn't work on an object).
EDIT: So it seems that there is a limitation within makeArray(): since an object property is not supposed to be named with a number, that function does not convert the rest of the object and the output is some kind of object-array hybrid (on which you cannot use array functions like shift()), so the quick-n-dirty solution I came to was to loop thru it like this:
var m = data.materials,
id;
for ( key in m ) { id = key; }
console.log( m[id].name );
It's not all that clean, so if there's a better way, please let me know.
p.s. The 1:{} is there in the first place because the controller returns multiple "materials" under certain conditions (which will never be true when this js is used).
You should use data.materials["1"].name
http://jsfiddle.net/nq4RE/
Jacob, I see you updated your question.
To use a variable, you simply call data.materials[your_variable_here].name
http://jsfiddle.net/nq4RE/1/
Did you try: data.materials[1].name?
But in my opinion using number as property name is misleading.
Related
Basically I have a complex object that retrieves the GPT API (google publisher tag) with this function:
googletag.pubads().getSlots();
The object value is something like this:
I need to know if there is a way to compare the value of each property with an X value without getting a problem of recursivity (because the object is huge and i need to to that validation several times)
Also, I tried to convert that object into a JSON with JSON.stringify(), and then tried to get the value with a regex, faster, but with this option, I have the problem with Cyclic Object Value.
Any suggestions ?
it's more simple. try it to convert it into an array and later use a filter for comparative with your value.
var objGoogle = {};
var arrayObjectGoogle = [objGoogle];
var filter = arrayObjectGoogle.filter(function(obj){
obj.yourAttr == yourValue; });
this will give you a second array with the values found it. later, index the array for pick up the value do you need.
I have a variable called uids
var uids = [];
Then I write some value to it property
uids[16778923] = "3fd6335d-b0e4-4d77-b304-d30c651ed509"
But before it
if (!uids[user.id]) {
uids[user.id] = generateKey(user);
}
This thing behaves ok. If I try to get the value of it property
uids[currentUser.id]
It will give me a value of this property. If I try to call some methods like
Object.keys(uids);
It will give me, what I expected. And here the mystery comes...
uids;
RAM rest in piece. See the node eating ram
I am very confused now. What's wrong?
This is because you are creating a huge array and node will reserve memory for it - who knows what comes. I'd say that's a scenario where you would use a Map (or a plain object, but Map feels better here.
var uids = new Map();
var key = 456464564564654;
if (! uids.has(key)) {
uids.set(key, generateKey(user))
}
You are creating an empty array (length is zero), then you assign some value to an arbitrary index. This will make the array grow as big as the index and assign the value to that index. Look at this example using node.js REPL:
> var a = []
undefined
> a[5] = "something"
'something'
> a
[ , , , , , 'something' ]
> a.length
6
Instead of creating an array, you could create a Map() or an common javascript object (singleton). Javascript objects behave like Maps but only Strings can be used as keys. If you assign a Number to be key, javascript will convert it to String automatically.
Personally, I would go with objects because they perform better. Instantiating an object takes longer than instantiating a Map (and it doesn't seem like you need to create several groups of "uids"), but once done, adding new keys and retrieving values from any key in faster when using common objects. At least that's how things go in my node.js v6.7.0 on ubuntu 14.04 but you could try for yourself. And it would also make the least alteration to your code.
var uids = {} // common/ordinary empty javascript object instead of array.
if (!uids[user.id]) { // getting value from one key works the same.
uids[user.id] = generateKey(user) // assignment works the same.
}
////
uids[16778923] = "3fd6335d-b0e4-4d77-b304-d30c651ed509" // key will be "16778923".
uids[16778923] // getting value for key "16778923" can be done using 16778923 instead of "16778923".
////
uids[currentUser.id] // still returning values like this.
Object.keys(uids) // still returning an array of keys like this. but they are all Strings.
I want to get the initial values (What I first defined it to be) of all the properties for one of my objects.
I want to do this at the "end" of my game.
I could just copy and paste the properties but the object is pretty big and im wondering if this would slow the site down a bit?
Thanks!
Code example:
var MyObject = {
nestedObject1 : {
//...
},
nestedObject2 : {
value1 : "Hi",
value2 : 1
},
objectProperty : 2637
}
How would I get all (Or maybe excluding one of the nested objects) of the properties to their intial value?
I don't quite fully understand how you want to get the initial values, at the end of your running. But probably the easiest way to do this is to just serialize your object to JSON using JSON.stringify.
var original = JSON.stringify(myObject)
Then at the end of your application when you want access to this original object again you can rehydrate it to a new JavaScript object:
original = JSON.parse(original);
I'm learning to program in Javascript and I'd like some help/clarification.
I declared an array that contains animal names. I defined a function that I use to split a string in two. Then I create an empty object literal and add an animal and corresponding breed. I'm trying to invoke the separateWords function in the object literal, but I need some clarification. Here's my code:
var myPets = ["Bengal Bobcat", "Beagle"];
var separateWords = function (string) {
return string.split(" ");
};
var nameCollection = {};
nameCollection.cat = separateWords(myPets[0]);
nameCollection.dog = myPets[1];
nameCollection.fish = null;
When I enter console.log(nameCollection) I get the following:
Object {cat: Array[2], dog: “Beagle”, fish: null}
cat: Array[2]
0: "Bengal"
1: "Bobcat"
length: 2
However, when I enter console.log( separateWords(myPets[0])), I see:
[“Bengal”, “Bobcat”]
I don’t understand why the value of cat shows up as Array[2].
The console displays it as Array[2] as it would be (potentially) unreadable if it expanded it fully. One way to see everything is to stringify it using JSON.stringify which goes through each item in the object recursively and calls toString() on it:
var myPets = ["Bengal Bobcat", "Beagle"];
var separateWords = function (string) {
return string.split(" ");
};
var nameCollection = {};
nameCollection.cat = separateWords(myPets[0]);
nameCollection.dog = myPets[1];
nameCollection.fish = null;
document.body.textContent = JSON.stringify(nameCollection);
You are assigning to cat the result of the separateWords() function call, passing myPets[0] as a parameter.
separateWords() returns an array and with the myPets[0] input it returns a new array with the "Bengal" and "Bobcat" values splitted by the whitespace.
The split() function is the one creating an array with the splitted values and this result is returned by your separateWords() function, which also is the value assigned to the cat object member.
Each browser implements its console like it wants.
So your browser decided to implement the behavior you describe.
If you don't like it, propose a better idea to the developers of this browser. Or use another browser.
I am going to assume you are using Chrome Developer Tools or Firebug.
Developer tools condenses arrays and objects into easily readable lines you then inspect further with. What I mean is, you push the little arrow next each line in the console log to further inspect each object. I will use pictures to explain this.
Here I am assigning an array and then assigning an element in an object to that array as so:
As you can see when I log the object it show's an Array[2] rather than expand the array. In this next picture I then expand the array to inspect it.
Why is this exactly? My first thought is ease of readability. If you have an app that is complex and you have numerous debugging console logs, you can see all the logs on single lines making it easier to hunt down specific logs. As well, if you have a very large and complex object, it is arguably easier to read all the root elements on each line without expanding all the objects and arrays found within that object recursively.
String.prototype.split() returns an array containing the two values in the string which have been split. Read through this.
nameCollection.cat = separateWords(myPets[0])[0]; // nameCollection.cat == Bengal
nameCollection.cat = separateWords(myPets[0])[1]; // nameCollection.cat == Bobcat
This is simply how javascript (and many other languages) work. When you try to print "nameCollection" javascript doesn't automatically do a nice job of printing the cat array. Instead, it simply prints some type related information, which in this case is saying "cat" is an array of length 2.
I'm trying to make helper functions to make use of the Google Analytics API, and I have a simple problem building strings. The scenario is, I have to apply a filter, and there may be n number of filters (a nominal amount, not more than 128 anyhow). I wanted to write a function which can take in the n strings and combine them with comma-separation in between.
I don't know if the number of arguments can be variable in javascript, and if it can take arrays as arguments in javascript (I am a newbie to JS), but I see no difference as variables are simply var and there is no datatype anywhere in JS (I come from a C++/Java background and find it confusing as it is). So I tried passing an array as an argument to a function so that the no. of things I can work with can be dynamic, decided by the elements in the array.
When I started searching for solutions, I came across this page. After that I recently came across this thread which also refers the same link and the format they have provided does me no good.
For the sake of clarity, let me provide the function definition I've written.
/**
* Utility method to build a comma-ed string from an array of strings
* for the multiple-condition requests to the GA API
*/
function buildString(strArray)
{
var returnString='';
for(var x in strArray)
returnString+=x+',';
return returnString = returnString.substring(0, returnString.length - 1);
}
And this is how I call it:
buildString.apply(this,[desc(visits),source])
where desc(visits) and source are both strings, so I assumed I'm sending an array of strings. Strangely, both this and null in the apply() call to the buildString function give me "0,1" as the return value.
Please tell me where I'm going wrong. Am I passing the array in a wrong manner? Or is my function definition wrong? Or is there some other simpler way to achieve what I'm trying?
Passing arrays to functions is no different from passing any other type:
var string = buildString([desc(visits), source]);
However, your function is not necessary, since Javascript has a built-in function for concatenating array elements with a delimiter:
var string = someArray.join(',');
You're over complicating things — JavaScript arrays have a built-in join method:
[ desc( visits ), source ].join( ',' );
EDIT: simpler still: the toString method:
[ desc( visits ), source ].toString();
The easiest would be to use the built-in join method:
[desc(visits), source].join(',');
Anyway, your problem was in the for..in loop
Instead of this:
for(var x in strArray){
returnString+=x+',';
}
You should have:
for(var i in strArray){
var x = strArray[i]; //Note this
returnString+=x+',';
}
Because for...in gives back the index/key, not the actual element as foreach does in other languages
Also your call should be:
buildString.call(this,[desc(visits),source]) or just buildString([desc(visits),source])
Cheers
Js argument can be any type and no limit to the number of argument,
But it is recommanded use 3-4 arguments at most, if there are more args, you can pass it as an object or array.
You don't need to worry about the type of args, js will do the job.
For example:
var func1 = function(a) {
console.log(a);
}
func1('good');
func1(1);
func1(['good', 'a', 1]);
func1({name: 'fn1', age: 12});
Anything you like!,
You can even define a function with three arguments, but only pass one is ok!
var func2 = function(a, b, c) {
console.log(a);
}
func2(1);
func2(1, 'good');
func2(1, 'good', 'night', 4);
And default array obj has many build-in func; for example:
var arr = ['good', 'night', 'foo', 'bar']; //define any thing in a array
str = arr.join(','); //you may get 'good,night,foo,bar'
var arr1 = str.split(','); // you may get ['good', 'night', 'foo', 'bar'];