Finding an item's index in an array - javascript

I was writing a function that takes two arguments, an array and a number, and returns the index of the number if it's present in the array. The issue I encounter is the fact that my code returns properly without the "else" part, however, when I add the code about returning "-1" it doesn't work properly and it seems as if the compiler only takes "return -1" into account, no matter what arguments I use. Could anyone help me solve this issue?
function search(arr, item) {
for(let i=0; i<arr.length; i++){
if(item===arr[i]){
return i;
}else if(item!==arr[i]){
return -1;
}
}
}
It's always giving me an output of "-1", when it's supposed to give the index of the "item" argument if it's presents in the first array argument.

You need return -1 outside the loop so it only returns -1 if it makes it all the way through the loop without finding something. If it finds something before that, it will return the index:
function search(arr, item) {
for(let i=0; i<arr.length; i++){
if(item===arr[i]){
return i;
}
}
return -1;
}
console.log(search([1, 2, 3], 5))
console.log(search([1, 2, 3], 2))

Think about this sequentially.
Let's say your array is [1, 2, 3] and you're looking for 3.
The function loops over the array. The first value considered is 1. That actives the else block and returns -1 before the other values are even considered. Remember return means end of function execution.
In any case, you can greatly simplify the function:
return arr.indexOf(item);

Related

Recursion better understanding

https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-javascript/use-recursion-to-create-a-countdown
We have defined a function called countdown with one parameter (n). The function should use recursion to return an array containing the integers n through 1 based on the n parameter. If the function is called with a number less than 1, the function should return an empty array. For example, calling this function with n = 5 should return the array [5, 4, 3, 2, 1]. Your function must use recursion by calling itself and must not use loops of any kind.
// Only change code below this line
function countdown(n){
if (n<1)
return [];
else{
const numbArray = countdown(n-1);
numbArray.push(n)
return numbArray;
}
}
console.log(countdown(5))
// Only change code above this line
comes out like [1 2 3 4 5] instead of [5 4 3 2 1]
I've been breaking my mind forever then I have completed it with the unshift method but felt like it wanted to me use push even though that sends data to the end of the stack
function countdown(max, currentN) {
if (currentN > max)
return [];
else if (currentN <= max) {
const numbArray = countdown(max, currentN + 1);
numbArray.push(currentN)
return numbArray;
}
}
console.log(countdown(5, 1))
// Only change code above this line
basically it just counts up to the end value given at start
else {
const arr = []
arr.push(n)
return arr.concat(countdown(n-1))
}
you can use this code replace, y question reason is y not understand recursion, try to break the point and watch the function execution step by step in the browser or vscode

Symmetrical Difference (Understanding the scope of this function)

I was completing a task of FCC which was to get the symmetrical difference of a varied number of arrays. Part of the reason I got stuck was because of my placement of the results array where I would push the unique elements to.I had it outside the function makeSym and I needed to have it inside which i discovered when checking out the hints page. But I dont know why.
function sym() {
var results = []; // I had the results array here rather than inside function makeSym
var allArrays = [];
for (var i = 0; i < arguments.length; i++) {
allArrays.push(arguments[i]);
}
function makeSym(arrOne, arrTwo) {
// when the results array was placed here, it worked
arrOne.forEach(function (a) {
if (arrTwo.indexOf(a) === -1 && results.indexOf(a) === -1) {
results.push(a);
}
});
arrTwo.forEach(function (a) {
if (arrOne.indexOf(a) === -1 && results.indexOf(a) === -1) {
results.push(a);
}
});
return results;
}
return allArrays.reduce(makeSym);
}
sym([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5]);
My question is why does this change my result, why don't I get the correct symmetrical difference. What is happening in the mechanics that I was missing.
the difference between these two placements was a return of 1,4,5 and a result of 1,3,4,5 (the correct answer should be 1,4,5)
I am assuming this has something to do with scope and closure and this is something I really want to understand more, any information would be helpful.
The second part of my question for anyone still with me, is why does the reduce work in this, what is the reduce doing. I understand its reducing to a single array my multiple arrays but how come the function makeSym doesnt do this alone, in my mind I should be able to execute the function with allArrays as a parameter then return results and complete the challenge this way, but this doesnt work and the reason why it doesnt work isnt obvious to me at all. Again any elucidation would help me understand this more and move forward. Cheers

Difference of Two Arrays

I have a quick question about finding the difference between two arrays. I found a chunk of JavaScript code that does what I want here and modified it a bit:
JS
function diffArray(arr1, arr2) {
var newArr = [];
var myArr = arr1.concat(arr2);
newArr = myArr.filter(function(item){
return arr2.indexOf(item) < 0 || arr1.indexOf(item) < 0;
});
return newArr;
}
diffArray([1, 2, 3, 5], [1, 2, 3, 4, 5]);
However, I'm not sure that I really understand what the filter function is doing here. Could anyone give me a clear explanation of how this works.
Note: I already know the basics of filter functions. I'm looking for a specfic explanation of this filter.
newArr = myArr.filter(function(item){
return arr2.indexOf(item) < 0 || arr1.indexOf(item) < 0;
});
The Array#filter function iterates over each element of the newly made array from concat function (containing every element from arr1 and arr2 arrays).
If at least one of the conditions arr2.indexOf(item) < 0 or arr1.indexOf(item) < 0 is fulfilled (returns true) at some iteration, the Array#filter function filters out (returns) that specified (actually iterated) element.
In case, if the iterated element is both in arr1 and arr2, the indexOf function will return it's index (which is higher than 0) - the condition will return false (it's not smaller than 0). We will receive then false || false which is false and that element won't be included in the newArr array, containing unique elements.
In case, if given element is only in one array (it doesn't exist in the second one - it's index will return -1 - it will fulfill the < 0 condition) - one of the conditions will return true, so the both conditions will become true || false which is true - given element will be included in the newArr array.
Filter is using a lambda to filter the list.
This essentially means that it executes the code between the { } and returns an array that meets the criteria. Your criteria are that the index of the item is greater than 0 in both arrays which is essentially just saying it's in both arrays.
you can read more here: https://www.w3schools.com/jsref/jsref_filter.asp
Easy way of thinking this is that filter function is internally creating an array.
The elements of this internal array are the ones that pass the condition in the callback function. This is possible since this decision is being made one element at a time in the callback function.
Condition arr2.indexOf(item) < 0 || arr1.indexOf(item) < 0 passes only for element 4 since at that time 4 is not present inside arr1. Since true is returned element 4 is added in the internal array. Ultimately 4 is returned in newArr.

Why does splice() behave weird?

I am trying to flatten multiple arrays into one and remove duplicate elements in the array for an exercise from FCC.
Specifically, the splice method shows one thing in the console but acts differently. Can anyone tell me why splice() is not deleting the the duplicates that I have identified with the nested loop?
function uniteUnique(arr) {
var arr1 = arguments;
newArr= [];
for(var i=0; i<arr1.length; i++){
for(var l=0; l<arr1[i].length; l++){
newArr.push(arr1[i][l]);
}
}
console.log(newArr);
for(var t=0; t<newArr.length; t++){
for(var p=0; p<newArr.length; p++){
if(newArr[t]===newArr[p+1]){
console.log("without splice ", newArr[p+1]);
console.log("with splice ", newArr.splice(newArr[p+1],1))
newArr.splice(newArr[p+1],1);
}
}
}
return newArr;
}
console.log(uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1]));
Will output [4,1].
But should output [1,3,2,5,4]
first Iteration Log:
without splice 1
with splice [3]
Second:
without splice 1
with splice [2]
Third:
without splice 2
with splice [4]
Fourth:
without splice 1
with splice [2]
You have three errors here:
There's no need to use p+1 here. Just use p.
splice expects an index as its first argument, but you are passing the value being considered for removal as an index to perform the removal. This is doesn't make sense. Instead of .splice(newArr[p], 1) you need .splice(p, 1).
You do not stop a value from being considered against itself as a potential duplicate. Your if condition must also include the condition ... && p!=t since newArr[t]===newArr[p] will always be (uselessly) true in case that t equals p
Modifying an array in its loop is something is not recommended. If you don't have to use splice, just create a brand new array and push values by searching and if not already exists in it.
function uniteUnique() {
var newArr = [];
for(var i=0; i<arguments.length; i++) {
var arr = arguments[i];
for(var j=0; j<arr.length; j++) {
if(newArr.indexOf(arr[j]) == -1) {
newArr.push(arr[j]);
}
}
}
return newArr;
}
console.log(uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1]));
In respect to the removing duplicates "in place" of your approach, splice is working fine and your algorithm is almost good, try to debug through each step of the iterations after the flattening, to remove the duplicates.
You are looping n squared times (because p = t and you iterate p * t times).
But, something is not doing what you want to, have a look at these:
if(newArr[t]===newArr[p+1]){ // HERE IT WON'T DO WHAT YOU WANT
I'm not going to give away the answer unless you mention it, I'm just trying to demonstrate that the problem does not rely with splice itself, rather than your algorithm.
The other line that you would need to modify would be this one
newArr.splice(newArr[p+1],1);
Basically with a few changes in these two lines, you would reach the goal to remove the duplicates.

Javascript Arrays - Find Duplicates [duplicate]

This question already has answers here:
Get all non-unique values (i.e.: duplicate/more than one occurrence) in an array
(97 answers)
Closed 8 years ago.
Here is my question...
Given an array populated with numbers as a function parameter, produce a resulting array which contains any duplicates number from the array.
For example, given the array [ 1, 2, 4, 4, 3, 3, 1, 5, 3 ] it should return [1, 4, 3]. For extra bonus points return a sorted array.
I am starting out with Javascript - I know the language however, using it in the correct way ( as one should ) I'm still getting to grips with.
My pseudo code for this would be to:
Create an array with the numbers above var numbers = [1, 2, 4, 4, 3, 3, 1, 5, 3];
Then create an empty array named "result" var result = [];
Create a for loop that goes through the var numbers to check for duplicates which will then populate the empty array "result" with the duplicates
for (var i = 0;i < numbers.length; i++) {
//This is where I'm stuck...
}
I'm not sure what to do within the for loop to populate the var result and to throw in to the mix... The given array has to be a function parameter which makes sense so you can change the numbers in one place.
Any feedback on my thought process on this so far is greatly appreciated but ultimately I am wanting to learn how to achieve this.
Here is a JSFiddle of my progress so far... http://jsfiddle.net/fbauW/
One way of doing this (and it's not the only way) is by checking for existing elements in the array. Take a look at JavaScript's lastIndexOf function:
http://www.w3schools.com/jsref/jsref_lastindexof_array.asp
It will return -1 if the object does not exist in your array, and if it exists, will return an index of a later position than you are in. So you can use an if statement in your loop that checks whether or not there is another index containing your number, and add it in to your results array IF AND ONLY IF the index you get back != the index you are currently on (if they equal, this means that there is only one of that element in the list).
If you need more help, comment here and I can type some code in!
Good luck!
Array.prototype.contains = function(k) {
for ( var p in this)
if (this[p] === k)
return true;
return false;
};
//this prototype function checks if an element is already in the array or not
//go through all the array and push the element to result if it is not
//this way we can eliminate duplicates
//result will contain the resultant array
function findDuplicates(Numbers) {
var arrayLength = Numbers.length, i, j, result = [];
for (i = 0; i < arrayLength; i++) {
for (j = 0; j < arrayLength; j++) {
if (a[i] == a[j] && i != j && !result.contains(a[i])) {
result.push(a[i]);
}
}
}
return result;
}

Categories

Resources