I am working on a function that accepts a JSON object as a parameter. Each property of the object passed in will be an array. I need to determine the length of each of these arrays.
What I won't know in advance are: the names of the properties, or how many properties there are.
How can I determine the length of each array? Again, I can't refer to any of the properties/keys explicitly because I won't know their names ahead of time. How do I reference each unknown property as an array?
Thank you in advance,
-RS
You can iterate over the object using a for...in loop to access each property.
for (var key in myObject) {
// Check to make sure the property is not part of the `Object` prototype (eg. toString)
if (myObject.hasOwnProperty(key)) {
console.log(key, myObject[key].length);
}
}
In the above example, we iterate over the properties of the object myObject and we log out their length values (assuming they are all arrays).
If by "JSON object" you mean that it is a string of JSON, you can first parse myObject into a true object by using myObject = JSON.parse(myObject) (which works in modern browsers) or myObject = eval("(" + myOjbect + ")") which is considered unsafe (but works in all browsers). After parsing, you may use the above technique to fine array lengths.
Note: Since you updated the post to specify that the object is JSON, you may not need the hasOwnProperty check, but it is safer to always use this test.
Use JSON.parse to convert JSON data to JS Objects, and then you can use Array's length etc properties.
var myObject = JSON.parse(myJSONtext, reviver);
JSON Reference: http://www.json.org/js.html
Related
For example, if I have an object like:
{"angeredoutsidecontrol":"1","difficultiespileup":"2"}
And then later in a for loop I can access the key of angeredoutsidecontrol , how can I get the value returned as 0, which would represent which place in the object this key is?
There is no guaranteed order for keys of an object.
Definition of object from an old - but still effective in this case - documentation:
4.3.3 Object
An object is a member of the type Object. It is an unordered
collection of properties each of which contains a primitive value,
object, or function. A function stored in a property of an object is
called a method.
If order really matters to you, use array instead. For example:
[{ "angeredoutsidecontrol": "1" }
{ "difficultiespileup": "2" }];
The order of JSON objects is not maintained, so you can't do this.
[Is the order of elements in a JSON list maintained?
var myMoods = ["angeredoutsidecontrol","difficultiespileup"];
and
myMoods.indexOf( 'angeredoutsidecontrol' )
gives you position in your list
I am pulling an object from backbone.js and when I stringify the object I see string literal
'[{"Name":"Testname","Address":"Testaddress","id":"444444444444444"}]'
However, when I assign the non-serialized object to a variable and try to access the 0th element, I get undefined. I would expect to get object
{"Name":"Testname","Address":"Testaddress","id":"444444444444444"}
Is JavaScript not treating
[{"Name":"Testname","Address":"Testaddress","id":"444444444444444"}]
as an indexed array of objects?
To access elements of Backbone.Collection by index, use the Collection#at method:
var first = collection.at(0);
Alternatively, you can use the Collection#first method, which is actually part of the underscore library, but is proxied to Backbone collections for syntactic sugar:
var first = collection.first();
The reason you're seeing the array representation in the serialized JSON is that by convention JSON.stringify looks for a method called toJSON on the object you give to it to stringify, and if one is found, the return value of that method will be used instead. The implementation of Collection#toJSON returns a clone of the collection's internal array of models, and thus the JSON output is an array.
Just tried
var arr = JSON.parse( '[{"Name":"Testname","Address":"Testaddress","id":"444444444444444"}]' );
and
console.log( arr[0] ); // => object
What you've described should work.
Crockford writes in http://javascript.crockford.com/survey.html:
"There are two ways to make a new array:
var myArray = [];
var myArray = new Array();"
So I'm confused by these two lines in some AJAX code I am reading:
var obj={}; // obj is an Object object (i.e. a hash table)
obj[4] = 'x'; // now obj is suddenly an Array object via an integer key?
In JavaScript are an object and an array really just the same thing, but with a variant on the key type?
In other words, is this the same as in php where we can use either a name (string) or an integer for a hash key?
I've Googled for an answer on this but can't seem to nail down an article which discusses this issue.
One possibility that comes to mind is that perhaps the first line is syntactic lint because the 2nd line overwrites the previous definition of obj as it creates a new Array object.
it does not become an array, it is simply an Object with a '4' property, like this:
var obj = {
'4': 'x'
};
it is just converted to a string when used as a property like obj['4'] = 'x';
Everything but primitive datatypes is an object in JavaScript. Objects can have a properties and there are two ways to access object properties:
Dot notation, foo.bar, which you can use as long as the property name is a valid identifier.
Bracket notation, foo['bar'] which you have to use if the key is not a valid identifier [spec]. For example, if it is a number, or contains a space or you have a variable with the name.
Hence, bracket notation is not a characteristic of arrays and if you see it, it does not mean the value is an array. It is simple one of two ways of accessing properties.
The elements of an array are just properties with numeric keys. Arrays are built on top of objects and implement some additional methods which treat these numeric properties in a special way. For example the .length property is automatically updated when you add new elements. But ultimately they are just normal properties.
In your example you have a simple object. You have to access the property with obj[4] or obj['4'] because obj.4 is invalid since 4 is not a valid identifier (basically everything that you can use as variable name is a valid identifier. var 4 = 'foo'; is invalid).
And since arrays are just objects, if you could use numbers as identifiers, you were also able to access an element with arr.4.
As far as I know, no, an object can't be coerced into an array. But, it can look and act like an array, and that's what's happening here. Numbers, and anything else that can be coerced to a string, are perfectly valid property names for Javascript objects, so
obj[4] = 1;
obj['spam'] = 2;
are both valid ways of setting a property on the object. That doesn't make the object an array. An Array is a special class of object with specific methods (.slice(), .concat(), etc) and a length property that's kept up to date with the number of items in the array.
Yes
Javascript Array is very different from tradition array, you can think of it as object.
var array = [1,2,3] is equivalent to var object = {'0' : 1, '1' : 2, '2' : 3}
except array inherited from Array.prototype and object inherited from Object.prototype, where Array.prototype will contain method such as length.
Javascript is a loosely-typed, prototype-based language. Even primitive types like a boolean can be treated like an object (though you aren't going to get far). Almost everything in javascript is, at root, an object.
Understanding this, an array IS an object. You can arbitrarily add properties to any object:
var xml = new XMLHttpRequest();
xml[4] = 'x';
console.log(xml);
That object is still an instance of XMLHttpRequest. It now has a property labeled 4 with a value of x. You can treat anything like this -- even a function:
var test_func = function () {
alert('woah!');
}
test_func[4] = 'x';
console.log(test_func[4]);
The take-away here is that the obj[key] = value notation is NOT indicative of an "array" type, like it is in languages such as PHP. Rather, it is an alternate way to access properties of any object, and is equivalent to obj.key = value (you can't use obj.4 = 'x', though, that's invalid syntax). The other take-away is that any object in javascript can be modified or used in pretty much any way. You shouldn't misuse objects, but you can
Check it out here: http://jsfiddle.net/w2AqJ/
Documentation
Array on MDN - https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array
Javascript "associative arrays" considered harmful by Andrew Dupont - http://andrewdupont.net/2006/05/18/javascript-associative-arrays-considered-harmful/
I have a js 'associative' array, with
array['serial_number'] = 'value'
serial_number and value are strings.
e.g. array['20910930923'] = '20101102'
I sorted it by value, works fine.
Let's say I get back the object 'sorted';
Now I want to access the first KEY of the 'sorted' array.
How do I do it? I can't think I need an iteration with
for (var i in sorted)
and just stop after ther first one...
thanks
edit: just to clarify, I know that js does not support associative arrays (that's why I put it in high commas in the Title).
2021 Update
Since ES6, properties with string keys are enumerated in insertion order. Here's a nice summary. My original answer from 2010 was correct at the time and is preserved below:
Original answer
JavaScript object properties are specified to have no order, much though many people wish it were different. If you need ordering, abandon any attempt to use an object and use an Array instead, either to store name-value objects:
var nameValues = [
{name: '20910930923', value: '20101102'},
{name: 'foo', value: 'bar'}
];
... or as an ordered list of property names to use with your existing object:
var obj = {
'20910930923': '20101102',
'foo': 'bar'
};
var orderedPropertyNames = ['20910930923', 'foo'];
Try this:
// Some assoc list
var offers = {'x':{..some object...}, 'jjj':{...some other object ...}};
// First element (see attribution below)
return offers[Object.keys(offers)[0]];
// Last element (thanks to discussion on finding last element in associative array :)
return offers[Object.keys(offers)[Object.keys(offers).length - 1]];
Actually JavaScript doesn't support associative arrays, so you can't loop through it in an implied order (e.g. you can't access it via the indexer property array[0] won't access the first element in your object). The syntax is what makes it look like it does, but in reality it doesn't. So you have no "Order" to your objects.
http://www.hunlock.com/blogs/Mastering_Javascript_Arrays
Javascript does not have, and does not
support Associative Arrays. However…
All arrays in Javascript are objects
and Javascript's object syntax gives a
basic emulation of an associative
Array. For this reason the example
code above will actually work. Be
warned that this is not a real array
and it has real pitfals if you try to
use it. The 'person' element in the
example becomes part of the Array
object's properties and methods, just
like .length, .sort(), .splice(), and
all the other built-in properties and
methods.
Just thinking off the top of my head, but could you have another array with the key value pairs swapped?
So the answer would be arrayKeyValueReversed['20101102'] = '20910930923';
When you sort the array, use the first item (array[0]) as the key to get the value in the arrayKeyValueReversed.
the index variable below is incorrectly initialized because f() will be returning stuff other than numbers, like strings. So what's the worst that can happen here? My testing seems to indicate that it has no effect, but now I am wondering...
function index(o, f) {
var index = []; // should be index = {};
each(o, function(k, v, o) { index[f(k, v, o)] = v; });
return index;
}
Javascript arrays are special objects that have an automatically set length property and inherit Array.prototype.
Unless you use a length property, there is no harm in treating an array as an object.
An array is an object, thus it can be treated as such without much side effects. Doing so however might result in some confusion, as the length property does not count non-numeric keys, and all the array prototype functions will likewise ignore them.
Just change [] to {}
You'll be creating an associative array, which is a valid JavaScript structure. Although, it is technically different than an object, you can interact with the array just like you would an object (for ... in to iterate, myarray[key] to fetch values). You may want to consider returning an object instead of an array if you suspect some keys will be strings.
"f() will be returning stuff other than numbers, like strings"
If f() only returns strings, then you're good to go, you're just using your array as an object and adding properties. The only downside is that the array itself remains empty, so for example you cannot count how many items you have added.
If f() can return both strings and numbers, it's going to create a mess. The loop will populate sometimes the array, sometimes the object properties.
I am not sure what you mean by "like strings", but if what f() returns is neither a number nor a string then it's not going to work.