myArray = [];
myArray.length;
myArray[1000000] = true;
myArray.length;
why does this return 100001?
ive read this in douglas crockford book and i dont understand what this
means
1000001, you've probably meant. An array is extended as soon as you access its element beyond current bounds. That is why after you touch its element no. 10⁶, it becomes of 10⁶ + 1 elements.
Maybe you check with a smaller index, like 10 and have a look to the values of the array.
The result is a sparse array with missing indices and one value on index 10.
The length is, as always, last index plus one.
var myArray = [];
console.log(myArray.length);
myArray[10] = true;
console.log(myArray.length);
console.log(myArray);
It returns 100001 because,
myArray = []; creates an empty array
That's why myArray.length; = 0
When you do myArray[1000000] = true;
that time actually what happens is it puts all values from 0th index to 999999th index to undefined and then puts you 1000000 value to true. so actually there are 1000001 values in an array.
That's why the length is 1000001
every function of array specifies that array works as a collection of things in a sequence which means you cant put value at random place even if you provide any random index the by the default value (undefined) will be available as a value for other places.
Arrays start at index 0, so if we have an array:
var arr = [1,2,3,4,5];
arr[0] is 1, arr[1] is 2 and so on, and the array's length is 5, because it contains 5 "elements". So, arrays start at index 0 (if you wanted to get the first element of the array, you would have to run arr[0], not arr[1], because arr[1] would be the second element) but .length counts the elements and starts with "1" for the first element, "2" for the second element, etc.
Now when you run this:
var arr = [1,2,3,4,5];
arr[200] = "whatever";
console.log(arr);
You will get this output:
(201) [1, 2, 3, 4, 5, undefined × 195, "whatever"]
So when we randomly added an element to the array at index 200 (which is actually the 201th element in the array, since arrays start at 0, not 1), the array's length just grew from 5 to 201 (the same thing can be seen in the output), and as you can see in the output, the array now contains the original 5 elements (1, 2, 3, 4 and 5), 195 ghost elements whose value undefined when you query them (don't bother what I mean by ghost element just now though), and 1 "whatever" element at its end (the output in the console would be slightly different if you manually inserted the 195 undefined elements, but don't bother yourself with such things for now).
So in your case, an array is defined (myArray), by default, it contains nothing, so it has a length of 0. Then you go on and say "I want to add an element at the 1000000th index of this array" (the line myArray[1000000] = true), don't let the true value of the added element confuse you! the output would be the same regardless of what followed the myArray[1000000] = part, so myArray[1000000] = "whatever" would give you the same output: an array whose length is 1000001. Here is the output of your array when used with console.log(..) (remember, the output would be the same even if "whatever" was inserted in place of true):
(1000001) [undefined × 1000000, true]
Also, remember, the array you get when you say var arr = []; arr[1000] = "foo" is sparse (If you are interested in sparse arrays)
The other comments have answered your question correctly as well but I decided to do so because: 1. I have a bad feeling the true part in myArray[1000000] = true is confusing you. 2. They explained the arrays-start-at-0 thing in a not-too-clear way.
Related
Hope I can describe this properly.
I've made a template HTML element to be filled up by info from an array when I run an onclick function. There will be different arrays so I've put them on a much bigger array. Now, what I was hoping to do, is to be able to call a random array off of the main Array then also be able to call the individual elements of the random array.
I tried creating an index randomizer and called on the arrays with it... it worked fine but you're bound to get the same set...
I've read and tried splicing, and the logic works fine. Console.logs shows that I got a random array, but when I try to pull out elements off the array I'm getting "undefined".
Here's a view of the code:
object00 = ["Cat", "Dog", "Cow", "Goat"];
object01 = ["Apple", "Banana", "Orange", "Manggo"];
.
.
.
mainArray = [object00, object01, . . .];
function next () {
if(mainArray.length == 0) return;
array = mainArray.splice(Math.floor(Math.random() *mainArray.length),1);
console.log(array); //displays [Array (4)]
console.log(array[1]); //displays undefined
}
I've read that spliced elements cannot be chained: is that the case?
Would appreciate it if anyone can explain to me what's going on and how I can work around it.
console.log(array); //displays [Array (4)]
If this happens your array must be array[0]
so to access a element you must do:
console.log(array[0][1]) //1. element
console.log(array[0][3]) //3. element
Or you can do this :
array = mainArray.splice(Math.floor(Math.random() *mainArray.length),1)[0]
Now you can access a element like this:
console.log(array[1]) //1. element
console.log(array[3]) //3. element
Your splice return a subarray. in your case is subarray with length 1, which include an array. So actually you have a 2 dimensional array. to access the target array you should first get it (array[0]).
Anyway, I think better solution will be just randomly sort the mainArray then just iterate it from index 0 to array.length-1.
to randomize array use:
mainArray = mainArray.sort((a,b) => Math.random() - .5)
live example:
var array = [1, 2, 3, 4, 5, 6, 7, 8];
var shuffled = array.sort((a,b)=> Math.random()-.5)
console.log(shuffled)
Basically, I'm writing a little algorithm that takes in a random array with only numbers and spits out the 2nd highest number in the array (assuming all entries in the array are numbers and there are at least 2 entries). Here is the code:
var secondGreatest = function(numberArray){
var array = numberArray;
var result = [];
for(var i = 0; i < array.length; i++){
if(array[i] === Math.max.apply(Math, array)){
result.push(array[i]);
array.splice(i, 1);
}
};
return result[1];
};
So what I'm doing is setting the input array of numbers to variable "array". Then I set variable "result" to an empty array.
In the for loop, I specify that if the array at the ith position equals the highest number of the array, push that number into the empty array and remove that number from the original array. Since the "result" array will have the order from highest to lowest number, I call result[1] to give me the 2nd highest number.
However, the result array only contains one entry and it's the highest number of the previous array. After that, the for loop seems to stop. I tried the "continue;" statement, but nothing works.
Any help as to why this doesn't work is appreciated.
Here is a shorter code, if you want to keep using the Math.max method.
var secondGreatest = function(numberArray){
var top1 = Math.max.apply(Math, numberArray);
numberArray.splice(numberArray.indexOf(top1));
return Math.max.apply(Math, numberArray);
};
var arr = [1,3,5,7,4,2];
alert(secondGreatest(arr));
You don't really need to iterate, and actually iterating would make it necessary to reset the for whenever you remove the max item. Tushar's answer in the comment is more compact though, and problably makes more sense.
When you do a splice, the array is being re-indexed and array.length which was cached becomes obsolete. This is why the for loop stops. You can start at the end and iterate backwards to fix this.
Looking at a beginner's javascript book and trying to understand a small browser program that builds a list with user input. The input box displays and enters strings as input until he just adds " " as an input. Then the list is shown in the browser.
Here's the code:
var userInput = " ";
var namesArray = new Array();
while ( (userInput = prompt("Enter name", " ")) != " ") {
namesArray[namesArray.length] = userInput;
}
namesArray.sort();
var namesList = namesArray.join("<br />");
var listHolder = document.createElement('div');
var list = listHolder.innerHTML = namesList;
document.body.appendChild(listHolder);
I just don't have understanding of the way the author adds items to the array. Would someone care to explain how namesArray[namesArray.length] = userInput builds an array?
Also here's a fiddle to try it out
Thansk in advance!
So what happens is that, we get a while loop that is going to keep asking for a name until we get an empty response:
while ( (userInput = prompt("Enter name", " ")) != " ")
It then uses the length of the inital namesArray to index the new value.
namesArray[namesArray.length] = userInput;
So we know that the array is initially empty. So on the first run the length is going to be zero! We also know that an index of 0 is the first item in an array. So it adds it to the array as the first item. After that, the array now has a length of 1 (since we just added an item). So on the next iteration we add the new item to the array at the index of 1, which increases its length to 2. This goes on forver until we break the while loop.
So if we break it down we'll see it more clearly:
//First iteration
newArray.length = 0;
newArray[newArray.length] = newArray[0]
//Second iteration
newArray.length = 1;
newArray[newArray.length] = newArray[0]
etc.
Basically .length is the size of the array so .length is the next index of the array without anything in it yet. He just adds the string to the end of the array .length which creates a new position at the end of the array. .length - 1 is the last element of the array so .length would create a new position at the end of the array. The next time through the loop the length will be one greater than the previous time because you added an element to the array.
The condition for the while loop (userInput = prompt("Enter name", " ")) != " ") will remain true as long as a name is entered each time.
Each time a name is entered, the length index is assigned the name. Each time a name is assigned, the length increases. As a result, the array will grow for each name entered.
Normally you could easily add an element to an array via the .push() method. For example:
var ary = []; // empty array
ary.push('foo'); // the ary array now has one element, 'foo'
Now array indices are zero-based, meaning that you refer to the first element as [0], the second as [1], etc. However, the .length property will return the actual number of elements in an array. So if we add 10 elements to our array, asking for the length will give us 10.
So what the person who wrote that code is doing, is using the fact that the .length property will allow you to target an element of the array that doesn't exist yet -- the element after the last element.
So for example, say we have an array with 10 elements. The length property will be 10, however the index of the last item will be nine, since the indices are zero-based. When the author of that code does:
namesArray[namesArray.length] = userInput;
They're also saying namesArray[10] = userInput;, and assigning userInput to the eleventh spot in the array (remember, zero-index).
Since this can be a little confusing to follow, most programmers will simply use the .push() method, which automatically tacks the value you pass it onto the end of the array without you having to specify an index.
Since arrays are indexed starting from zero, the last element in the array always has the index
namesArray.length - 1
Therefore, the next available unused index is always equal to
namesArray.length
You can safely set values at this index and know that they will be added to the end of the array.
So, you have this array:
var namesArray = new Array();
And you may know you can insert array values like this:
namesAray[0] = 'first value';
namesAray[1] = 'second value';
namesAray[2] = 'third value';
Now, the code is like this:
namesArray[namesArray.length] = userInput;
So, here the namesArray.length brings you the size of the array. Ok, as above you see I've added three values to the namesArray namesArray[0],namesArray[1], namesArray[2]. So the current size of the array is 3 and namesArray[namesArray.length] is equal to namesArray[3] and now here the input value is inserted.
So, like this the code inserts new array value to the end index of array which is checked by while ( (userInput = prompt("Enter name", " ")) != " ") {
Hope you understood.
I have this code that fetches data and puts it into an array:
this.$httpGetTest(this.test.testId)
.success(function (data: ITestQuestion[]) {
self.test.qs = data;
});
It works and populates the array starting with self.test.qs[0].
However many times my code references this array (which contains a list of questions 1...x)
I must always remember to subract 1 from the question number and so my code does not look clear. Is there a way that I could place an entry ahead of all the others in the array so that:
self.test.qs[0] is null
self.test.qs[1] references the first real data for question number 1.
Ideally I would like to do this by putting something after the self.test.qs = and before data.
Push values at start of array via unshift
self.test.qs.unshift(null);
You need to use Splice(), It works like:
The splice() method changes the content of an array, adding new elements while removing old elements.
so try:
self.test.qs.splice(0, 0, null);
Here mid argument 0 is to set no elements to remove from array so it will insert null at zero and move all other elements.
Here is demo:
var arr = [];
arr[0] = "Hello";
arr[1] = "Friend";
alert(arr.join());
arr.splice(1,0,"my");
alert(arr.join());
You can start off with an array with a null value in it, then concat the questions array to it.
var arr = [null];
arr = arr.concat(data);
You could do something like:
x = [null].concat([1, 2, 3]);
Though there isn't anything wrong with doing something like:
x[index-1]
I'd prefer it to be honest, otherwise someone might assume that the index value returned is 0 based.
Regarding this post (Remove Duplicates from JavaScript Array) on creating a new array of unique values from another array.
Code in question:
uniqueArray = myArray.filter(function(elem, pos) {
return myArray.indexOf(elem) == pos;
})
Using this as the test data:
var names = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"];
Desired result is an array with only unique values:
var unique_names = ["Mike","Matt","Nancy","Adam","Jenny","Carl"];
Where I'm at:
I understand that filter will run a function on each member of the array, and that elem is the element being reviewed, and that pos is its index. If something causes that function to return false, then that element will not be included in the new array. So walking through it, this happens:
Is myArray.indexOf("Mike") the same as 0? Yes, so add "Mike" to the new array.
Is myArray.indexOf("Matt") the same as 1? Yes, so add "Matt" to the new array.
Is myArray.indexOf("Nancy") the same as 2? Yes, so add "Nancy" to the new array.
[repeat for all elements. All pass.]
Basically I don't get why the 2nd Nancy would evaluate to false.
The indexof is the index of the first appearance of the element, so the second Nancy would get the index of the first Nancy, and would be filtered out.
6) Is myArray.indexOf("Nancy") the same as 5? No (it's 2, just like it step 3), so skip the duplicated "Nancy".
indexOf gives you the first occurrence of the item.