Get the length of an array within a JSON object - javascript

I want to find out how many items are in my JSON object. I have seen many answers but they all deal with a common value to loop through. I am wanting the results to tell me that there are 2 items in this object. Any help would be great!
[{"manager_first_name":"jim","manager_last_name":"gaffigan"}]

You could use Object.keys in newer browsers. It would return an array of all the keys in the object, and that array would have a length property that will tell you how many items there are in the object :
var arr = [{"manager_first_name":"jim","manager_last_name":"gaffigan"}];
var length = Object.keys(arr[0]).length;
FIDDLE
In non-supporting browsers, you have to iterate
var arr = [{"manager_first_name":"jim","manager_last_name":"gaffigan"}];
var i = 0;
for (var key in arr[0]) i++;
FIDDLE

You can do this:
var arr = [{"manager_first_name":"jim","manager_last_name":"gaffigan"}],
length = 0,
obj = arr[0]; // Get first obj from array
for(var k in obj){
if( obj.hasOwnProperty(k) ) {
length++;
}
}
console.log(length); // Shows 2
You should use hasOwnProperty because you can also extend an Object with functions, there could otherwise also be count als keys.
Links:
hasOwnProperty

Try
var jsonArr = [{"manager_first_name":"jim","manager_last_name":"gaffigan"}];
var itemCount = JSON.stringify(jsonArr).split('":"').length - 1;
This is, of course, a rather coarse(and unreliable) way of doing it, but if you just want the item count, this should work like a charm.

Related

Iterating JavaScript object with strings as keys

I am building a JavaScript array, which has strings as keys.
The array should have an object at every entry. My object looks like this (a console.log of my variable rIds):
Now, the length of this object is 0, which makes it impossible to iterate it.
I want to iterate every key, so I can retrieve and access my list of ids (rIds[key].productIds).
Code:
var rIds = [];
var response = RR.data.JSON.placements;
console.log(response);
$(response).each(function (placementId) {
var placement_name = this.placement_name;
rIds[this.placement_name] = {
productIds: []
};
$(this.recs).each(function (recIndex) {
var pid = this.pid;
pid = getRandomId(19341610, 19341746);
rIds[placement_name].productIds[recIndex] = pid;
});
});
var count = '<%=ViewBag.Get("RecommendationCount") %>';
console.log(rIds);
console.log(rIds.length);
$.each(rIds, function (index, val) {
console.log(val); // This should work as expected.
});
What did I try?
I found the following snippet, which does not work in IE8. However, this does not really help be, even though Object.keys(rIds).length results in the correct length.
for (var index = 0; index < Object.keys(rIds).length; index++) {
console.log(rIds[index]);
}
However, this code does not make my access the object.
Tl;dr & question
How do I iterate my JavaScript object which has strings as keys, so I can access the individual entries?
The Object.keys() function returns an array containing the property names of the object.
var keys = Object.keys(rIds);
for (var i = 0; i < keys.length; ++i) {
console.log(rids[keys[i]]); // object value
}
Alternatively, you can use the .forEach() method:
Object.keys(rIds).forEach(function(key) {
console.log(this[key]);
}, rIds);
Finally there's the venerable for ... in loop:
for (var key in rIds) {
if (rIds.hasOwnProperty(key))
console.log(rIds[key]);
To support versions of IE before IE9 you're kind-of stuck with for ... in, though you can find mostly-correct "polyfills" for Object.keys() and Array.prototype.forEach() at MDN.
To supplement Pointy's answer, you can also use jQuery's $.each (since you're already using jQuery elsewhere) to iterate over each key/value pair in your rIds object:
$.each(rIds, function(key, value) {
console.log(value);
});

JavaScript - Array behaves like object

I'd like to ask a question about JavaScript arrays.
Does the array behave like an object when we use for..in loop to iterate. I mean in this case can indexes take the role of properties(keys).
While you can do for..in syntax on an array, you shouldn't because you will will iterate over any properties you may have assigned to the array.
Example:
var array = [0, 1];
array.three = 2;
for (var p in array){
console.log(array[p]); //print 0, 1, 2
}
for(var i = 0; i < array.length; i++){
console.log(array[i]); //prints 0, 1
}
So, when dealing with arrays you should always use the for var i approach to avoid running into unexpected behavior.
As everything in JS, an array is an object.
It means you can use an array as a prototype :
var obj = Object.create([]);
console.log(obj instanceof Array); // true
obj[0] = "value 1";
obj.test = "value of property test";
for(var i in obj) console.log(obj[i]); // "value 1" "value of property test"
or any other thing you would do with an object, including using a for ... in loop.
However, the length property is updated with the highest (integer) index of the array +1.
var arr = ["one","two"];
arr.length; // 2
That's why it's preferred not to use for ... in loops when you only want to iterate on the values of the array : you can use for(var i=0,var l=arr.length;i<arr.length;i++) instead.
Yes ,you can access array like an object Only if array keys are string,
var sdf = [];
sdf['asd'] =45;
sdf[32] =8674;
console.log(sdf.asd) // WORKS
console.log(sdf.32) // Error
Array.prototype.forEach is what you want. Just be mindful of browser support or use a framework that corrects for unsupported browsers: http://kangax.github.io/compat-table/es5/#Array.prototype.forEach
for in should be used for iterating over object properties because order is not guaranteed.

Get last element of a JSON object in JavaScript

I got a json object in JavaScript like:
var json = {"20121207":"13", "20121211":"9", "20121213":"7", "20121219":"4"};
without knowing the name of the last key. (The keys are in ascending order)
How can I read the value (and key) of the last element?
var highest = json[ Object.keys(json).sort().pop() ];
Object.keys (ES5, shimmable) returns an array of the object's keys. We then sort them and grab the last one.
You can't ensure order in a for..in loop, so we can't completely rely on that. But as you said the keys are in ascending order, we can simply sort them.
Try this:
var lastKey;
var json = {"20121207":"13", "20121211":"9", "20121213":"7", "20121219":"4"};
for(var key in json){
if(json.hasOwnProperty(key)){
lastKey = key;
}
}
alert(lastKey + ': ' + json[lastKey]);
If you don't need to support old JS engines:
var lastKey = Object.keys(json).sort().reverse()[0];
var lastValue = json[lastKey];
Don't assume the keys are in order. Get the keys, and then sort them, and then grab that largest value after the sort.
Object keys are typically unordered, but looking at the keyset you are using, I made the assumption that you are looking for the highest date in the json keys:
var json = {"20121207":"13", "20121211":"9", "20121213":"7", "20121219":"4"};
function getMaxFromKeys(json) {
var m;
for (var i in json) {
if (json.hasOwnProperty(i)) {
m = (typeof m == 'undefined' || i > m) ? i : m;
}
}
return m;
}
var latestDate = getMaxFromKeys(json);
ECMCA script specifications (javascript specifications) do not require browsers to maintain order of the properties of an object.
Related to for-in this is what ECMCA 5 specs say:
"The mechanics and order of enumerating the properties (step 6.a in
the first algorithm, step 7.a in the second) is not specified."
Related to the Object.keys method:
"If an implementation defines a specific order of enumeration for the
for-in statement, that same enumeration order must be used in step 5
of this algorithm."
It does not make sense to say get the last defined property. You can sort the properties based on the name and get the last one, but if what you want is order then keep an array.
let obj = <your_object>
let last_key = Object.keys(obj)[Object.keys(obj).length - 1]
let last_value = <your_object>.last_key
OR
let last_value = Object.values(obj)[Object.values(obj).length - 1]
getJsonLastElement(json)
{
let len = json.length
return json[len - 1]
}

Can't reference array by index

I have an array defined as:
var subjectCache = [];
I then have some code to build it up, which is working ok.
However, if I try to reference the array by an index, e.g.:
var x = subjectCache[0];
or
var x = subjectCache[1];
I get undefined.
Also subjectCache.length is always 0 (zero).
if I try to reference it by its key, e.g.:
var x = subjectCache['12345'];
it works.
Is this normal? Shouldn't I be able to reference it by its index whatever?
I'm using Internet Explorer, if it makes a difference (and it probably does :( )
[Edit]
this is the code I'm using to build the array, although I really don't think it is to blame.
It's a callback from a webservice call. This is working fine and the array is being populated.
var subjectCache = [];
var subjectCacheCount = 0;
function refreshSubjectsCallback(data) {
// update subjects
// loop through retrieved subjects and add to cache
for( i=0; i < data.length; i++ )
{
var subject = data[i];
var subjectid = subject.SubjectId;
subjectCache[subjectid] = subject;
subjectCacheCount += 1;
}
}
[/Edit]
You're probably assigning keys manually instead of using subjectCache.push() to add new elements to the array:
var array = [];
array['foo'] = 'bar';
console.log(array.length); // 0
The length attribute isn't going to reflect those changes the way you'd expect:
> var a = [];
undefined
> a[100] = 2; // The previous `100` entries evaluate to `undefined`
2
> a.length;
101
Instead, use an object:
var object = {};
object['foo'] = 'bar';
for (var key in object) {
var value = object[key];
console.log(value);
}
From your symptoms, it sounds like you are trying to treat the array as an associative array.
In Javascript, arrays work like this:
var a = [];
a[1] = 10;
alert(a.length);
Objects work like this:
var o = {};
o.myProp = true;
o["myOtherProp"] = false;
Arrays only work with numeric keys not strings. Strings assign properties to the object, and aren't counted as part of length nor it's numeric indices.
When building the array, make sure you are assigning to a numeric position within the array.
No, it will not work, because you haven't created arrays but objects.
you will have to access it by its key.
var x = subjectCache['12345'];
If this works and subjectCache.length doesn't, I think you are making an object not an array. You are confused.
Somewhere along the road you lost the array, and the variable subjectCache points to a different kind of object.
If it was an array, it can't have the length zero and contain an item that is reachable using subjectCache['12345']. When you access an item in an array it doesn't make any difference if you use a numeric index or a string representing a number.

Getting Length of Object in Javascript / jQuery

I am trying to set up an array in jQuery and I then need to do a for loop on it. But it seems that I cant use an associative array for some reason?
var items = new Array();
items['foo'] = 123456;
items['bar'] = 789012;
items['baz'] = 345678;
items['bat'] = 901234;
alert(items.length);
This is just a test, but it return 0?
You can't make associative array in JavaScript like what you want, instead you can use Object.
For example:
var items = {
foo : 123456,
bar : 789012,
baz : 345678,
bat : 901234
}
And to calculate the length you can do:
var getObjectSize = function(obj) {
var len = 0, key;
for (key in obj) {
if (obj.hasOwnProperty(key)) len++;
}
return len;
};
Use: getObjectSize(items); // output: 4
For more see here.
Another one is:
Object.keys(items).length;
But not supported by all browsers.
var items = new Array();
items['foo'] = 123456;
The problem lies in the very first line. You believe that you are adding an item to the array at the index foo, but you are actually adding a property to the items variable with a key foo and value 123456. If you were to type items.foo it would give you back your 123456.
The problem with this approach is that adding a property to an array does not magically increase it's length.
If you want to have non-numeric indexes, you need to use an object instead of an array:
var items = {
foo: 123456,
bar: 789012,
baz: 345678,
bat: 901234
};
Another approach might be to set up two different arrays, which you construct in parallel:
var items = [], items2 = [];
items.push('foo');
items2.push(123456);
// etc.
alert(items2.length);​
The efficiency of this approach depends on how you'll use it. If you're only going to loop through the list of items and do something to each of them, this approach may be more efficient. But if you need to use it like an associative array (items['foo']), then you're better off building an object.
The .length property returns the highest numerical index of the array. Thus, in your case, there is no numerical index and it returns 0. Try
items[98] = "something";
items.length will be 98..! Use the .length property with caution, and if you also want to count the non-numerical indici, loop over the Object (an Array is also an Object) and count its ownProperties.

Categories

Resources