Multiple Arrays, need to find Nested Array Position - javascript

Well i have this slight issue in which i have multiple arrays as show in the image below. As you can see the first array # pos 2&3 have arrays there!
What i need is:
To find their respected position in that array
Then to get the length of all the showing arrays leaving out the nested arrays.
This is the result of the below code, i was assuming that with this logic that the first instance of the lengths should be 2 rather than 4
here is code that i['m currently trying to make work:
for (var n = 0; n < objCollection.length; n++) {
//works out how many value circles are needed if the value nodes do not have an array in any given position
for (var i = 0; i < objCollection[n].getPropertyValues().length; i++) {
if (objCollection[n].getPropertyValues()[i].constructor !== Array) {
//get the length of all the arrays that do not have any nested arrays
console.log(objCollection[n].getPropertyValues().length);
}
}
}
To add some context objCollection is an array containing my own custom objects each object (in this instance there are 7) are things you're trying to describe I.E a person, each object then has a property such as HAIR and finally each property has a value such as brown.
In the image below those are the values of earlier defined properties to use the image as an example the property associated with 'greys Atatomy' is the Name of the Show property.

So you want to get the number of non-Array items in an Array?
var arr = ['a', [], 'b', []];
arr.filter(function (e) {return !Array.isArray(e);}).length;
// 2

Related

Length of the javascript array does not change after deleting the element from it

I am trying to copy one array values into another, but without breaking the links that is associated with this array other words i can not just assign the new array to this value, thats why i cannot use methods like slice() or concat().
Here is the code of the function that does the thing:
self.updateBreadcrumbs = function (newBreadcrumbs) {
var old_length = self.breadcrumbs.length;
var new_length =newBreadcrumbs.length;
var j = new_length > old_length ? new_length: old_length;
for (var i = 0; i < j; i++) {
if(old_length < i+1){
self.breadcrumbs.push(newBreadcrumbs[i]);
continue;
}
if(new_length < i+1){
delete self.breadcrumbs[i];
continue;
}
if (self.breadcrumbs[i].title !== newBreadcrumbs[i].title) {
self.breadcrumbs[i] = newBreadcrumbs[i];
}
}
}
My problem is that length of the array does not change when i delete something from the array.
P.S If you know any easier way to do this i am totally open for propositions.
Length of an Array can never change by deleting elements in it.
However It can be altered with splice
eg.
var arr=[1,2,3,4,5]; //length 5
arr.splice(0,1); //length 4
Unlike what common belief suggests, the delete operator has nothing to do with directly freeing memory. delete is only effective on an object's properties. It has no effect on array length
The splice() method changes the content of an array by removing
existing elements and/or adding new elements.
More about Splice
The length property of an Array object is a property that is maintained by it's methods, it is not an inherent characteristic of the object itself. So, if you take an action on it that is not one of Array's own methods, it will not update the length property. In this case, it is the splice method that you would want to use ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice )
Interestingly, you can change the makeup of an array by directly altering its length . . . for example, if you have an array with 6 elements in it and you were to change its length property to 5 (i.e., array.length = 5;), it would no longer recognize the 6th element as being part of the array.
More on the length property: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length
An Array is (aside from its prototype methods) not much more than a simple object. The difference is in the length property which has a spcieal setter method, and the different way of adding a new property.
If a property is added to the object, its name is tested for being a numerical value and whether this value is >= the current array length. if so, the internal length is updated.
If the length is set, it is checked, whether the new value is smaller than the old one, and if so, all own properties with a property name that is a numerical value and >= the new length will be deleted.
If you delete an indexed element from an array, it will just be deleted (and accessing this index later will return undefined, as it would do with any non-existent property). It won't change the array length, nor will increasing the array length create any properties for the added index positions (sparse array). Using [] or new Aray[10000] will both create Arrays with exactly the same memory footprint. Just the length property has a different initial value.
This is completely different from Arrays in other languages, where an array of size n will have n storage spaces reserved for the elements (being pointers to objects or being native value types). So in other languages, creating an array with a given size and filling it is faster than creating an empty array and adding values (in which case each time a larger consecutive space must be allocated and the array must be copied to this larger memory psoition before adding the element). OTOH, accessing the elements of an JS array is somewhat slower (as they are just named properties which have to be located in the property list first) than in other languages where an element is at its given, fixed position.
This answer will not help if you use array, but.
If you still need to delete item by key and you can use object:
$o = {'blue' : '', 'apple' : '', 'red' : ''};
console.log(Object.keys($o).length); // will output 3
delete $o['apple'];
console.log(Object.keys($o).length); // will output 2

pushing the innerText from 3 elements results in an array with 5 values?

I'm getting two extra/unexpected array entries that are undefined. These show up when I iterate over an array of element nodes with 3 entries and push the values into another array:
I have a select element with 4 options in it. I want to put the last 3 options.innerText into an array
<select>
<option>skip me</option>
<option>text1</option>
<option>text2</option>
<option>text3</option>
<select>
I made a variable and grabbed the nodes:
var options = document.querySelectorAll('select option:not(:first-child)')
this gave me an array with 3 option elements in it as confirmed in the console
>>options
<<[<option>text1​</option>​,
<option>text2​</option>​,
<option>text3​</option>​]
options.length is 3.
iterating over the array proceeds as expected, but also includes a function in the log?
>>for (i in options){console.log(options[i])}
<< <option>text1</option>
<option>text2</option>
<option>text3</option>
<< 3
<< function item() {[native code]}
When I iterate over the array and push the innerText into a new array, I get not 3, but 5 entries in the array
>>var texts = [];
>>for (i in options){texts.push(options[i].innerText)}
This gives me an array texts with 5 values: ['text1','text2','text3',undefined,undefined]
texts.length is 5
Why am I getting those two extra array entries?
I'm sure this is something elementary that I just haven't come across yet, can anyone explain?
Try iterating through a general for loop.
for (var i = 0; i < options.length; i++) {
texts.push(options[i].innerText)
}
http://jsfiddle.net/d02urj1n/
Because for (i in options) iterates through the properties of the options object. for/in was made to iterate over enumerable properties.
Array indexes are just enumerable properties with integer names and
are otherwise identical to general Object properties. There is no
guarantee that for...in will return the indexes in any particular
order and it will return all enumerable properties, including those
with non–integer names and those that are inherited.
So, while you may find some iterations of forEach or you can roll out your own, it is safer to loop over an array using a normal for loop.
If you are using jquery use $.map() like so...
var opts = $("select > option:not(:first-child)");
var texts = [];
$.map(opts, function(val, key){
texts.push(val.innerText);
});
I suggest to use basic JavaScript For Loop, just like following :
for (var i=0 ; i < options.length ; i++){
console.log(options[i]);
}
//That will give you the expected result
<option>text1</option>
<option>text2</option>
<option>text3</option>
NOTE : Please take a look at Why is using “for…in” with array iteration such a bad idea?.
Hope this helps.
Looping through the properties in the object gives you the following items:
"0": <option>text1</option>
"1": <option>text2</option>
"2": <option>text3</option>
"length": 3
"item": function () {[native code]}
The reason that you get a length and item property also, is that the object is not an array, it's a NodeList object. It works as an array for methods that expect an array because it has a length property and numbered items, so it's what's called an array-like object. The for( in ) loop doesn't expect an array.
Loop through the items as if it was an array, using the length property:
var texts = [];
for (var i = 0; i < options.length; i++){
texts.push(options[i].innerText);
}
Thanks everyone, after some more inspection I did find some injected code objects! The standard for loop worked as expected. I didn't realize that for... in... would bring in inherited properties. Learn something new everyday.

How to get the correct array length

In my code i initialize array then put a value inside it why the output be 0 ?in spite of this should be 1
var changedfields=[];
changedfields['product']="productname";
alert(changedfields.length);
You're creating an associative array (normal arrays have an numeric index) but are actually trying to build a HashMap (a key, value pair). Use Objects or ES6 Maps.
I hope the following example will help you out:
var changedfields = {}; // create an object
changedfields['product']="productname";
var keys = Object.keys(changedfields); // returns the keys of the object ['product']
alert(keys.length);
I would suggest to read more about datastructures in javascript and avoid associative arrays in general.
Length of a JavaScript object (that is, associative array)
associative array versus object in javascript
Your question is interesting. Following is the answer.
First of all Arrays in Javascript are object type.
The first line you wrote creates an empty array and it's type is object.
var changedfields=[];
The second line you wrote creates a property called product of changedfields and sets the value to productname. It allows you add the product property because Javascript Array type is object. If you just had var changedfields; you could not add this property.
changedfields['product']="productname";
The third line you wrote simply finds the length of the empty array.
alert(changedfields.length);
In Javascript associative arrays are achieved using object. But if you want to add the product name in changedfields array. You could use push method like below and check the length:
changedfields.push('productname');
console.log(changedfields.length);
Javascript numerical indexed array length
So the Javascript numerical indexed array length can be calculated this way:
console.log(array.length);
console.log(changedfields.length); // in your case
The Javascript associative array length
The Javascript associative array (object) length can be calculated following ways:
Option 1:
Object.len = function(obj) {
var objLen = 0;
for (i in obj) {
obj.hasOwnProperty(i) ? objLen++ : '';
}
return objLen;
};
console.log(Object.len(changedfields));
Option 2:
console.log(Object.keys(array).length);
console.log(Object.keys(changedfields).length); // in your case
Note: This has issues with Internet Explorer 8, Opera etc

Javascript two dimensional arrays [duplicate]

This question already has answers here:
How can I create a two dimensional array in JavaScript?
(56 answers)
Closed 8 years ago.
I have declared a two-dimensional array, like so:
a = [[]]
However, when I try to give a second dimension value using a first dimension index other than 0, it doesn't work:
a[1][0] = "foo" //returns error
Is there a better way around this than manually defining every index you need as an array, i.e.:
a[1] = [];
a[2] = [];
a[3] = [];
//et cetera
N-Dimensional arrays do not exist in javascript - you have to just make arrays containing arrays as elements.
You're getting an error because a = [[]]; declares an array with one element, which happens to also be an array. Therefore a[0] is the internal array, but a[1] does not exist because you never declared it. The easiest way to properly declare a "two dimensional array" would be to use a loop:
var outerArray = [];
var numInternalArrays = 5;
for (var i = 0; i < numInternalArrays; i++) {
outerArray[i] = [];
}
If you know how many elements the root array should have you could do something like this:
var arr =
(Math.pow(2,10)-1).toString(2) // Binary string of 1s. Its length being 10
.split('') // Create an array from this string
.map(function(){return [];}); // Map a new empty array to each index
console.log(arr); // [[],[],[],[],[],[],[],[],[],[]]
This accomplishes the same thing:
for(var arr = [], i=10; i--; arr[i]=[]);
No need to declare arr outside of the for-loop since javascript doesn't have block scope, it will be added to the scope in which it is executed.
a = [[]]
This is an Array, with the first item being an array. Which is why indexing into the first item still works (a[0][0]).
If you want to access the second item as an array, you need to create your array as
a = [[],[]]
See this question for examples of
How can I create a two dimensional array in JavaScript?
If I understand correctly, use a loop:
for (var i = y; i--; a[i] = []);
There are no multidimensional arrays in javascript.
What you are doing is an array of arrays, but the outermost array has only one element (i.e. element 0) whose value is another array. So a[1] (or more generally a[1][x]) is invalid since the outermost array has only one element.
So you can do a[0][x] = "foo" but not the other way around.
So you can either initialize the array with a for loop or do something like var a =[[][][][][]];
You can have the array of arrays start as in:
var a = []; // start with the column array
Then when you want to put something in location [i][j] we can call 'i' the row-index and 'j' the column-index.
if (!a[i]) { // check for row existing
a[i] = []; // .. and create it if not
}
a[i][j] = 'foo'; // put something in the array cell
Note that this only works because we are always putting something in the new row array right after we create it. It might not work if you put 0 or "" in there instead of 'foo'.
There are a lot of things in javascript that are 'false' including 'null' and 'undefined' and '0' and I just don't know if an empty array or an array with one element that is an empty string are considered false. So you would have to do some experimenting with how, exactly to detect a missing row array so you can add it in.

Why array in JavaScript showing wrong length

I am learning Javascript. As a part of learning, I came across following scenario, where I expect the a1.length (the last line of the code) to show 201, but it shows 101, any Idea?
var a1 = new Array();
for (var i = -100; i<=100; i++)
a1[i] = i;
for (var i in a1)
{
document.write(i + "=" + a1[i])
document.write("<br>");
}
document.write(a1.length);
I'll convert my original comment to a more thorough answer.
Array indexes that are counted in .length go from 0 and up. Negative indexes are considered properties of the object, not array values. As you can see from the ECMAScript spec below, array indexes are essentially just certain types of property values given some special treatment.
From section 15.4 of the ECMAScript spec:
15.4 Array Objects
Array objects give special treatment to a certain class of property names. A property name P (in the form of a String value) is an array index if and only if ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal to 2^32. A property whose property name is an array index is also called an element. Every Array object has a length property whose value is always a nonnegative integer less than 2^32 . The value of the length property is numerically greater than the name of every property whose name is an array index; whenever a property of an Array object is created or changed, other properties are adjusted as necessary to maintain this invariant. Specifically, whenever a property is added whose name is an array index, the length property is changed, if necessary, to be one more than the numeric value of that array index; and whenever the length property is changed, every property whose name is an array index whose value is not smaller than the new length is automatically deleted. This constraint applies only to own properties of an Array object and is unaffected by length or array index properties that may be inherited from its prototypes.
Also, you should never "iterate" arrays with a for-in-loop:
for (var i in a1)
That iterates all enumerable properties of a1 which will include all array indexes, but could also include other properties. If you want to iterate only array elements with a for loop, you should use the other form:
for (var i = 0, len = a1.length; i < len; i++)
It is slightly more typing, but a lot safer.
Or, in more modern browsers, you can use the .forEach() method.
It is because arrays in Javascript are zero-based, i.e. they start from zero and go up to length - 1.
You usually write your for loops to be bound by less-than operator like this:
for(i = 0; i < arr.length; i++) {
// do something with arr[i]
}
The array length is defined as the index of the last element plus one. Arrays do not need to be continuous, which can give strange results:
var myArray = [];
myArray[-42] = 1
myArray[1000] = 2;
document.write(myArray.length); // 1001

Categories