How are items being added to this javascript array here? - javascript

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.

Related

Check if element exists in array if not print not found

I am new to JS. I have task:
Given names and phone numbers, assemble a phone book that maps friends' names to their respective phone numbers. You will then be given an unknown number of names to query your phone book for. For each queried, print the associated entry from your phone book on a new line in the form name=phoneNumber; if an entry for is not found, print Not found instead.
Note: Your phone book should be a Dictionary/Map/HashMap data structure.
Input Format
The first line contains an integer, , denoting the number of entries in the phone book.
Each of the subsequent lines describes an entry in the form of space-separated values on a single line. The first value is a friend's name, and the second value is an -digit phone number.
After the lines of phone book entries, there are an unknown number of lines of queries. Each line (query) contains a to look up, and you must continue reading lines until there is no more input.
Note: Names consist of lowercase English alphabetic letters and are first names only.
Here is my code. But i cant check name exists in array or not. Js includes didnt work?
function processData(input) {
//Enter your code here
const n = parseInt(input);
const d = [];
for (var i = 1; i <= n; i++){
var line = input.split('\n').splice(i,1);
let x = line[0].split(" ");
d[x[0]] = x[1];
}
console.log(d)
let m = n;
while (true){
try{
name = input.split('\n').splice(m+1,1);
if ( d.includes(name)){
console.log(name,'=',d[name])
} else console.log('Not found')
m +=1;
}
catch(err){
break
}
}
}
name is the result of a splice on an array, which means it's an array, but you've filled d with strings, so d.includes(name) is looking for a newly-created array inside an array of strings. No array is ever equal to a string (without conversion, which includes doesn't do).
If you meant name to be the entry you removed from the array with splice (since it returns an array of removed entries), you'd need to use [0] on the end to get it:
name = input.split('\n').splice(m+1,1)[0];
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^
I haven't gone through the code to look for other issues, but that will at least look for a string in the array of strings rather than looking for an array in the array of strings.
Side note: You appear to be relying on getting an error to stop your loop, but beware that accessing beyond the end of an array is not an error in JavaScript, you just get the value undefined.

Assigning Array Value Gives Undefined Key

I have a multidimensional array of 100 trucks. Each truck holds several boxes.
I insert the first box of each truck by splicing from the box array to the truck array:
removed = allBoxes.splice(x, 1)[0];
trucks[i] = {0: removed};
Because I know it's the first box, I can put the {0:. But to add the next box, I want it to be dynamic.
I can insert it at the right place, but the key is undefined instead of 1 for the next box.
removed = allBoxes.splice(x, 1)[0];
trucks[i][trucks[i].length] = removed;
You can see the results here: Instead of undefined:, can it say 1? Whenever I try to add a variable in the array, it just writes out the variable string, not the value.
As #JordanBurnett mentioned, it wasn't an array. I had to count how many objects were in the array. Using the below code (from this question) gave the desired result:
var size = Object.keys(trucks[i]).length;
trucks[i][size] = removed;

How does this line " return fileNameParts[fileNameParts.length-1]; " work?

function getFileExtension(i) {
if (i.indexOf(".") < 0) {
return false;
}
var filenameParts = i.split(".");
return filenameParts[filenameParts.length-1];
}
Here's the whole code. I understand it all except for the last line. I know what it does, but I don't know how or why. The second to last line splits the string at the ".", and then how does the last line actually get all the letters on the right side of the string?
By calling var filenameParts = i.split("."); an array is created containing the different parts. Imagine we use the filename test.txt and we use that string to split, we'll get an array like so:
filenameParts = ["test", "txt"]
Because the index of the first item in an array is 0, and we need the last item in the array, we call filenameParts.length-1 to get to the last item.
More information about javascript arrays can be found here.
The .split() function returns an array of strings, not a string. The expression filenameParts[filenameParts - 1] fetches the last element of the array.
filenameParts.length delivers the count of the filenameparts, split in the line above. filenameParts[number] delivers the one item of the array, which is positioned at number. -1 because arrays start at 0 not at 1. So it delivers the last item of the array. Clear?
filenameParts is an array and you read a single value with it's index. A value in this case is one part of the string between the ".".
filenameParts.length is equal to the count of values inside the array. As an array index starts with 0 you have to subtract 1 to get the index of the last value.
It looks like your function getFileExtension is designed to return the file extension of a given file. For example getFileExtension('image.gif') would return gif.
In the line (given that i is set to image.gif):
var filenameParts = i.split(".");
filenameParts will be an array, where image.gif has been split on the period. So filenameParts = ['image', 'gif'] where element zero is image and element one is gif. Remember that array indices are zero-based!
In the last line:
return filenameParts[filenameParts.length-1];
the function itself will return the last element in the filenameParts array (['image', 'gif']) which is gif. The part filenameParts.length-1 says get the length of the filenameParts array (which is 2), subtract 1 (which is 1), and return that element of the filenameParts array. So we return filenameParts[1] which is the last element of the array (remember, array indices are zero-based).
To get the last element of the array we could also have done
return filenameParts.pop();
because the pop() function returns the last element of an array.
var filenameParts = i.split('.') returns an array of made of the splitted elements of i
filenameParts[filenameParts.length-1];
select the last element of that array

Can someone explain to me why this loop doesn't give me the desired result?

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.

How does this snippet for removing duplicates from an array work

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.

Categories