This question already has answers here:
Get all unique values in a JavaScript array (remove duplicates)
(91 answers)
Closed 5 years ago.
I wrote a function in javaScript that checks if it is the first time the numbers has been seem, if so, it will be added to the the array. For some reason the first number is always repeating it, Ex:
if we pass [1,1,1,2,3,3,4,5]
it will print out [1,1,2,3,4,5] instead of [1,2,3,4,5]
Could anyone tell me what I'm missing ??
Thank you in advance.
var numbers = [1,1,1,1,1,2,3,4,4,4,5,5,6,6,6,8];
function eliminateDup(arr){
var myArr = [];
for(var i = 0;i<arr.length;i++){
if(!myArr[arr[i]]){
myArr.push(arr[i]);
}
}
return myArr;
}
console.log(eliminateDup(numbers));
This comparison doesn't make sense :
if(!myArr[arr[i]]){
It is true only if !myArr[arr[i]] can be converted to true.
You get twice 1 in the target array myArr because both arr[0] and arr[1] equals to 1 and myArr has an undefined element at the 1 index for the two first iterations at the time where the conditional statement is executed.
First iteration
i = 0
arr[0] = 1
myArr[1] = undefined
So if(!myArr[1]) is true.
You add 1.
Second iteration
i = 1
arr[1] = 1
myArr[0] = 1 // now valued but not used in the test
myArr[1] = undefined;
So if(!myArr[1]) is true.
You still add 1.
Third iteration
i = 2
arr[2] = 1
myArr[0] = 1
myArr[1] = 1
So if(!myArr[1]) is false.
nothing is added.
You should rather check whether the current value is not contained in the target array before adding it in the target array :
if(myArr.indexOf(arr[i])==-1){
myArr.push(arr[i]);
}
use this condition instead, for push
if(myArr.indexOf([arr[i])===-1)
myArr.push(arr[i]); will push to back of the array myArr (just like a stack) and thus element '1' will be at index 0.
myArr[arr[i]] checks if element at index arr[i] exists which it won't so will push another 1.
As suggested above use indexof() which will just search and give an index if the element exists.
Related
Im just wondering who can explain the algorithm of this solution step by step. I dont know how hashmap works. Can you also give a basic examples using a hashmap for me to understand this algorithm. Thank you!
var twoSum = function(nums, target) {
let hash = {};
for(let i = 0; i < nums.length; i++) {
const n = nums[i];
if(hash[target - n] !== undefined) {
return [hash[target - n], i];
}
hash[n] = i;
}
return [];
}
Your code takes an array of numbers and a target number/sum. It then returns the indexes in the array for two numbers which add up to the target number/sum.
Consider an array of numbers such as [1, 2, 3] and a target of 5. Your task is to find the two numbers in this array which add to 5. One way you can approach this problem is by looping over each number in your array and asking yourself "Is there a number (which I have already seen in my array) which I can add to the current number to get my target sum?".
Well, if we loop over the example array of [1, 2, 3] we first start at index 0 with the number 1. Currently, there are no numbers which we have already seen that we can add with 1 to get our target of 5 as we haven't looped over any numbers yet.
So, so far, we have met the number 1, which was at index 0. This is stored in the hashmap (ie object) as {'1': 0}. Where the key is the number and the value (0) is the index it was seen at. The purpose of the object is to store the numbers we have seen and the indexes they appear at.
Next, the loop continues to index 1, with the current number being 2. We can now ask ourselves the question: Is there a number which I have already seen in my array that I can add to my current number of 2 to get the target sum of 5. The amount needed to add to the current number to get to the target can be obtained by doing target-currentNumber. In this case, we are currently on 2, so we need to add 3 to get to our target sum of 5. Using the hashmap/object, we can check if we have already seen the number 3. To do this, we can try and access the object 3 key by doing obj[target-currentNumber]. Currently, our object only has the key of '1', so when we try and access the 3 key you'll get undefined. This means we haven't seen the number 3 yet, so, as of now, there isn't anything we can add to 2 to get our target sum.
So now our object/hashmap looks like {'1': 0, '2': 1}, as we have seen the number 1 which was at index 0, and we have seen the number 2 which was at index 1.
Finally, we reach the last number in your array which is at index 2. Index 2 of the array holds the number 3. Now again, we ask ourselves the question: Is there a number we have already seen which we can add to 3 (our current number) to get the target sum?. The number we need to add to 3 to get our target number of 5 is 2 (obtained by doing target-currentNumber). We can now check our object to see if we have already seen a number 2 in the array. To do so we can use obj[target-currentNumber] to get the value stored at the key 2, which stores the index of 1. This means that the number 2 does exist in the array, and so we can add it to 3 to reach our target. Since the value was in the object, we can now return our findings. That being the index of where the seen number occurred, and the index of the current number.
In general, the object is used to keep track of all the previously seen numbers in your array and keep a value of the index at which the number was seen at.
Here is an example of running your code. It returns [1, 2], as the numbers at indexes 1 and 2 can be added together to give the target sum of 5:
const twoSum = function(nums, target) {
const hash = {}; // Stores seen numbers: {seenNumber: indexItOccurred}
for (let i = 0; i < nums.length; i++) { // loop through all numbers
const n = nums[i]; // grab the current number `n`.
if (hash[target - n] !== undefined) { // check if the number we need to add to `n` to reach our target has been seen:
return [hash[target - n], i]; // grab the index of the seen number, and the index of the current number
}
hash[n] = i; // update our hash to include the. number we just saw along with its index.
}
return []; // If no numbers add up to equal the `target`, we can return an empty array
}
console.log(twoSum([1, 2, 3], 5)); // [1, 2]
A solution like this might seem over-engineered. You might be wondering why you can't just look at one number in the array, and then look at all the other numbers and see if you come across a number that adds up to equal the target. A solution like that would work perfectly fine, however, it's not very efficient. If you had N numbers in your array, in the worst case (where no two numbers add up to equal your target) you would need to loop through all of these N numbers - that means you would do N iterations. However, for each iteration where you look at a singular number, you would then need to look at each other number using a inner loop. This would mean that for each iteration of your outer loop you would do N iterations of your inner loop. This would result in you doing N*N or N2 work (O(N2) work). Unlike this approach, the solution described in the first half of this answer only needs to do N iterations over the entire array. Using the object, we can find whether or not a number is in the object in constant (O(1)) time, which means that the total work for the above algorithm is only O(N).
For further information about how objects work, you can read about bracket notation and other property accessor methods here.
You may want to check out this method, it worked so well for me and I have written a lot of comments on it to help even a beginner understand better.
let nums = [2, 7, 11, 15];
let target = 9;
function twoSums(arr, t){
let num1;
//create the variable for the first number
let num2;
//create the variable for the second number
let index1;
//create the variable for the index of the first number
let index2;
//create the variable for the index of the second number
for(let i = 0; i < arr.length; i++){
//make a for loop to loop through the array elements
num1 = arr[i];
//assign the array iteration, i, value to the num1 variable
//eg: num1 = arr[0] which is 2
num2 = t - num1;
//get the difference between the target and the number in num1.
//eg: t(9) - num1(2) = 7;
if(arr.includes(num2)){
//check to see if the num2 number, 7, is contained in the array;
index1 = arr.indexOf(num2);
//if yes get the index of the num2 value, 7, from the array,
// eg: the index of 7 in the array is 1;
index2 = arr.indexOf(num1)
//get the index of the num1 value, which is 2, theindex of 2 in the array is 0;
}
}
return(`[${index1}, ${index2}]`);
//return the indexes in block parenthesis. You may choose to create an array and push the values into it, but consider space complexities.
}
console.log(twoSums(nums, target));
//call the function. Remeber we already declared the values at the top already.
//In my opinion, this method is best, it considers both time complexity and space complexityat its lowest value.
//Time complexity: 0(n)
function twoSum(numbers, target) {
for (let i = 0; i < numbers.length; i++) {
for (let j = i + 1; j < numbers.length; j++) {
if (numbers[i] + numbers[j] === target) {
return [numbers.indexOf(numbers[i]), numbers.lastIndexOf(numbers[j])];
}
}
}
}
I don't find an answer in the replies to this kind of question already been asked.
I don't understand, why console throws this error "TypeError: Cannot read property 'length' of undefined" , when my for-Loop contains this condition
for (let i = 0; i <= res.length; i++) {
arr.push(res[i].length);
}
Without equal sign it works.
I don't get why. I thought setting i=1 would work. But it does not.
Could anyone explain please, why I get the error when given the condition
i>**=**res.length; (with equal sign)
Complete code
function findLongestWordLength(str) {
var arr = [];
var res = str.split(" ");
for (let i = 1; i < res.length; i++) {
arr.push(res[i].length);
}
return Math.max(...arr);
}
findLongestWordLength("May the force be with you");
Thank you and happy new year.
Because the index of an array is always length - 1.
You can say. Suppose you have the array of length 2
const ar = ["a", "b"]
and if you check the length of this array it will show 2 but the max index of this array is 1 only.
So when you loop through the length of the array then it goes up to index 2 and res[2] is undefined
Basically the indices of an Array are zero based.
If you loop until the length, the last index is one over.
array = [1, 2, 3] // length === 3
If you loop until 3,
array[3]
you get undefined, or if the element should be an object, then you get the above mentioned error.
Arrays are zero based in JavaScript.
For example: If you have 3 numbers in an array var arr = [10,20,30] then the indices of these numbers will be 0 1, 2 i.e. You can access 10 with arr[0], 20 with arr[1] and 30 with arr[2].
Note that length of this array will be 3. So when you iterate in your loop from 0 to length you go one index extra therefore you get undefined. Either go from 0 to <= res.length - 1 or 0 to < res in your loop.
This question already has answers here:
How to get first N number of elements from an array
(14 answers)
Closed 5 years ago.
i would like to get the first 3 elements of an array of variable length. i've sorted my array and i would like to get a Top 3.
here's what i've done :
var diffSplice = this.users.length - 1;
return this.users.sort(this.triDec).splice(0,diffSplice)
my "solution" work only for an array of 4 element ( -1 )
Is there a better way to use the splice method ?
Thanks for your help
You could use Array#slice for the first three items.
return this.users.sort(this.triDec).slice(0, 3);
Don't you want to use a const value for diffSplice like
var diffSplice = 3;
return this.users.sort(this.triDec).slice(0,diffSplice)
try running
let arr = [1, 2, 3, 4, 5];
console.log(arr.slice(0, 3));
refer to Array Silce
Fill out the deletecount for Splice:
var sortedArray = this.users.sort(this.triDec);
return sortedArray.splice(0, 3);
check MDN
I was working on a code in which I needed to convert strings to numbers in an array. I tried this-
for(var i=0;i<arr.length;i++)
{
arr.push(parseInt(arr[i]));
arr.shift();
}
What turned out to be weird for me is that the values returned were correct but at the end of array, the values of last and second last element always turned out to be same(i.e. the expected value of the last element),whereas this worked perfectly fine-
l= arr.length;
for(var i=0;i<l;i++){
arr.push(parseInt(arr[i]));
}
var temp=begin.splice(0,l);
I am curious that why the first method didn't work because according to me it should. Any kind of help would be great.
Let the array arr = ["2016","09","01"]
Now lets move the loop step by step (which you can easily do using chrome debuggger tool)
var arr = ["2016","09","01"]
for(var i = 0; i < arr.length; i++) {
arr.push(parseInt(arr[i]))
arr.shift()
}
console.log(arr)
Iteration 1
i = 0
arr.length = 3
take index 0 element, shift out 1st, push to the last
arr = ["09", "01", 2016]
Iteration 2
i = 1
arr.length = 3
take index 1 element, shift out 1st, push to the last
arr = ["01", 2016, 1]
Iteration 3
i = 2
arr.length = 3
take index 2 element, shift out 1st, push to the last
arr = [2016, 1, 1]
And boom, your result is on the table.
Hence, the 1st algo is a very very bad one.
Your first function is reading and deleting array elements at the same time in 1 iteration . Refer fail fast array.
Dry run:
'1','2' is initial array .
After 1st iteration it will be '2',1
Now 2nd iteration has i=1
But ar[1]=1 , so it will again push 1 and final array is 1,1 .
Hope you got the point.
Better solution:
Use JavaScript map.
var newAr=ar.map(function(a){
return parseInt(a);
});
You changed both the input array and the index (i) which you used to read from the input.
Assuming you have the ["2016","09","12"] then on the first iteration i is 0 and you do your arr.push(parseInt(arr[i])); arr.shift() then the result is:
["09","12", 2016] and i is incremented to 1 so at the next step you read "12" instead of "09"
This question already has answers here:
forEach on array of undefined created by Array constructor
(5 answers)
Closed 6 years ago.
Array(3) yields [ , , ], which has a length of 3.
[1, 2, 3].forEach loops 3 times, as expected.
Neither Array(3).forEach nor [ , , ].forEach loops at all, however.
Why is this? I thought I'd discovered a way of doing something n times without using for loops, and am disappointed to find it doesn't work!
forEach() executes the provided callback once for each element present
in the array in ascending order. It is not invoked for index
properties that have been deleted or are uninitialized (i.e. on sparse
arrays)
Example from MDN:
Fiddle
function logArrayElements(element, index, array) {
console.log('a[' + index + '] = ' + element);
}
// Notice that index 2 is skipped since there is no item at
// that position in the array.
[2, 5, , 9].forEach(logArrayElements);
// logs:
// a[0] = 2
// a[1] = 5
// a[3] = 9
Have a look at MDN article.
.