Arrays and loops - javascript

I need some help with this, I'm stuck in JS Arrays & Loops, I don't know why this is telling me that if the function is empty is not returning "0".
function sumArray (numbers) {
// your code
var numbers = [1, 2, 3, 4];
if (numbers !== undefined) {
const sum = numbers.reduce((a,b) => a+b, 0)
return sum
}
else if ( numbers === []);{
return 0
}
}
sumArray();
I tried to return 0 when the array is empty, but I' don't know what I'm missig.

Beside the missing code, you could just return the result of reduce.
return numbers.reduce((a, b) => a + b, 0);
Some other annotations:
Do not redeclare and assign numbers, because you the the array as parameter.
Do not check against undefined here, because you get always an array as parameter.
You can not check an empty array with comparing another (literally) empty array, because arrays are objects and you compare different object references. For checking if an array is empty, take Array#length property and compare against zero.

The first issue is that you have a line ensuring that numbers is always an array containing 1,2,3,4; so the empty condition will never be met. So that line needs to be removed.
A second issue is that you have an extraneous semicolon that is subtly changing the logic.
The following logic will run the empty statement if numbers references the array object you just created using the array literal synax ([]); then a block will be evaluated outside of the else..if block, returning zero.
else if ( numbers === []);{
return 0
}
If you want to check if an object is an array you can use Array.isArray(foo).
If you want to check if an array is empty, you can test its length (if(myArray.length === 0) ...)
So what you probably meant to write was:
else if (numbers.length === 0) {
return 0
}
...but it turns out that the reduce code will work correctly if the array is of zero length; so that bit of logic is not necessary.
What you want is something like this:
function sumArray(numbers) {
if (!numbers) return 0;
return numbers.reduce((a,b) => a + b, 0);
}
console.log(sumArray())
console.log(sumArray([]))
console.log(sumArray([1, 2, 3, 4]))

Related

Incorrect value returns

I use this function:
function search (){
v = [[2.0], [3.0], [4.0], [5.0]]
if(v.indexOf(2.0) != -1){
Logger.log ('if')
}else{
Logger.log('else')
}
}
editing
My real need is in the values of words like this
I was answered about numbers so I did not change and only added
function search (){
v = [["One"], ["two"], ["three"], ["four"]]
if(v.indexOf("One") != -1){
Logger.log ('if')
}else{
Logger.log('else')
}
}
And instead of "if" returning to me, "else" returns to me.
I apologize for the broken English
You input array is a multi/two dimensional array. You are searching for 2.0 which is actually embedded inside another smaller array. Try changing the function to below.
function search() {
v = [
["One"],
["two"],
["three"],
["four"]
]
if (v.findIndex(e => e[0] === 'One') != -1) {
console.log('if')
} else {
console.log('else')
}
}
search();
You have an array of arrays, so trying to use indexOf on the array of arrays will not work for your case. One option is to use flat and some in conjunction to flatten the array of arrays to one array and then check if the value is found inside the flattened array:
function search (){
v = [[2.0], [3.0], [4.0], [5.0]];
if(v.flat().some((a) => a === 2.0)){
console.log('if');
}else{
console.log('else');
}
}
search();
Did you mean to write
v = [2.0, 3.0, 4.0, 5.0];?
Because that will print out 'if'.
Reason is that in your example, each element of v array is an array of it's own.
If you really want it to be an array of arrays, then to make it work you can do this in the if statement:
if ( v.flat().includes(2.0) )
flat converts it from an array of array that contain a number, to an array of numbers.
includes is a nicer method to check if the array contains a value - no need to check for index :)
array.indexOf() is not applicable for nested array. If your array is primitive types then it's working, but if array is non-primitive types then through indexOf you can't match the value.
Use this instated of your function:
v.findIndex(ele => [...new Set(ele)][0] == 2.0) >=0 ? 'if' : 'else'

Don't understand how this code can detect the length

var data = [1, 2, 3, 5, 2, 1, 4];
// iterate over elements and filter
var res = data.filter(function (v) {
// get the count of the current element in array
// and filter based on the count
return data.filter(function (v1) {
// compare with current element
return v1 == v;
// check length
}).length == 1;
});
console.log(res);
I understand all the line in this code, but I don't understand how it can detect the length==1.
(My opinion) Because it loop though every single element in the array and return boolean value either true or false so how it can use to detect the length?
This code is to get the array element that only appear once in the array.
The return true is not to return the boolean, but when you return true from inside a filter, that item gets added to the resulting array of filter function.
The process here is called chaining of methods. On line 11, first, the filter is applied to the data array, then the .length method is applied to the result of the filter, which will be an array of equal length or less than the number of elements in the data array. Then finally only once the return is called, which will be a boolean used for the outer filter.
Another example:
function reverseString (inputString) {
return inputString.split("").reverse().join()
}
In the above example, the function returns after the split, then reverse on the split's result, then join on the reverse's result. The final resulting string is only returned.
Don't think about it as lines of code. Split each segment of code into its true meaning my padawan
data.filter(function (v1) {
// compare with current element
return v1 == v;
// check length
})
filters the data array to return an array of elements from data such that every element in it is equal to v
By checking if its length is 1, you want to return true if the the array has only 1 element.
So,
var res = data.filter(function (v) {
// return true if there is only 1 element in data which is equal to v
});
Which basically means, we are filtering data, and returning a new array where every element is such that it has only one occurrence in the array.
The function for filter returns a boolean, but filter itself returns an array.
So, for example:
array.filter(function(element) { return element >= 0; });
says that the function function(element) { return element >= 0; } will be applied to each element in array. Then, if the result of the function is true, that element will exist in the final, filtered version of array (which is what the filter function returns), or will not exist if the result is false.
In effect, all negative numbers from array will be filtered out because they return false.
What your code is saying is the following: For every element in data, filter data to keep only the elements equal to the current one. If this filtered list has only one element, then it can only be our current element. Therefor this element exists only once and should be kept in the final result, so we return true if .length == 1. In the end, once this is done for every element, filter is smart enough to convert those results of true and false into an array of the elements that produced true and leave out those that produced a false.
I will describe the filter method step by step in detail.
First, it takes a condition. then it returns an array with all values which passed the condition successfully
so think about this block of code as a condition
return data.filter(function (v1) {
// compare with current element
return v1 == v;
// check length
}).length == 1;
so let's take the first part of the condition
data.filter(function (v1) {
// compare with current element
return v1 == v;
// check length
})
and let's say we gonna start with the first element 1 , so how many times v1 === v ? the answer is two times so it will return this array [1, 1]
so forget the condition we wrote in the first lines and think about it like that [1,1].length === 1.
So [1,1].length === 1 will return false
The same will happen with number 2. so let's talk about the number 3. it will be [3].length === 1 which is true which will go to the upper level and that's why the res will be finally [3, 5, 4]

Turning a string into an array and saving it as a new array, doesn't return original array

This function cleans up a string (removes all non-alphanumeric characters including underscores) then splits each letter into an array so that it can be reversed, then checked against the original.
At console.log(cleanStr) , it is returning the reversed array but I do not know why.
function checkIfPalindrome(str) {
var cleanStr = str.toLowerCase().replace(replace, "" ).split("");
var reversedStr = cleanStr.reverse();
console.log(cleanStr); // why is this returning reverseStr, the reversed array?
if (cleanStr == reversedStr){
return true
}
return false
}
checkIfPalindrome("five|\_/|four");
The reverse() method reverses an array in place - it mutates the array it's called on. Try creating a new array instead:
const cleanStr = str.toLowerCase().replace(replace, "" ).split("");
const reversedStr = [...cleanStr].reverse();
At console.log(cleanStr) , it is returning the reversed array but I do not know why.
Because reverse reverses it in place.
Separately, you have a problem here:
if (cleanStr == reversedStr){
If they were different arrays, that would always be false, even if they had the same contents.
If you want to make a copy of the array and then reverse it, throw a .slice() in there:
var reversedStr = cleanStr.slice().reverse();
// -----------------------^
...and then compare after turning them back into strings:
if (cleanStr.join("") === reversedStr.join(""))
(I'd probably change those variable names, too, as they don't refer to strings.)
And finally, any time you find yourself writing:
if (x == b) {
return true;
}
return false;
back up and write
return x == b;
instead. :-)

Removing duplicates from array ( understand the code)

I'm looking at an exercise and having trouble understand how the following works ( I'm trying to remove duplicates from an array)
var arr = ['a','b','c','a','b','d','e','f'];
var uniqueArray = arr.filter(function(item,pos){
return arr.indexOf(item) == pos;
});
My attempt to understand
Here item takes on all of our values in arr. Lets go through an iteration
First item = 'a' and pos = 0. Ok. now we want to only filter on the basis of if the index of 'a'is the same as 0
Here indexOf(a) == 0.
Great! this is true, lets put it in the new array.
Now lets move forward to where we see a again, namely at pos = 3
arr.indexOf(a) == 3
Wait... Doesent this meet our requirement as well? How does this even remove duplicates?
indexOf returns just one integer value, and it is the index of the first found item. So, when pos is 3 (and the item is a), indexOf will return 0 (because the first index of a is 0), 0==3 is false and the element will be removed.
Then, when the pos is 4 (and item is b), indexOf returns 2, the index of the first found b.
As for the objects, they can't have duplicate keys. Each new key will automatically overwrite the old one, so there won't be any duplicates.
Look:
var obj = {a:1, a:3, b:2,c:5,b:4};
console.log(obj)
nicael is right. indexOf(item) is just a function that goes through the array and looks for the first time item appears in the array, and returns the position in the array. In your example, if there is an a at 0 and a at index 3, then indexOf('a') will return position 0, while the value of pos is 3, so the filter returns false.
FOLLOW UP:
indexOf() has another parameter called the fromIndex, which lets you start the search from a position other than the beginning of the array. In this case, you can specify to skip over the first time 'a' occurs by doing arr.indexOf('a', 1) which starts the search at position 1, not 0. In this case the function would return true since the next 'a' is at position 3.
Can I use filter on an object?
No, because filter is a specific function of an Array object. You can get the keys of the object by doing a filter on Object.keys(myObject) since keys() returns an array.
Using your example:
var keyArray = Object.keys(myObject); //object can't have duplicate keys
keyArray.filter(function(item, index) {
return keyArray.indexOf(item) == index; //will never be false
});
Hashtable is the best way to eliminate the redundant values
Here is the code :
char arr[] = ['a','b','c','a','b','d','e','f'];
//it will contains all 26 places as zero (A - Z)
char hashArray[26]={0}
int i; //for iteration;
for(i=0;arr[i]!='\0';i++)
{
//it will subtracte the ascii value of the letter
//from 'a' so that we have the values from 0 to 26)
hashArray[arr[i]-'a']=arr[i];
}
for(i=0;i<26;i++)
{
if(hashArray[i]!=0) //to Ensure the positon has the character
{
printf("%c",hashArray[i]);
}
}

How does this recursive function end?

This is from nodeschool's functional javascript workshop. Here is the code as it appears there:
function toUpperArray(items) {
if (!items.length) return [] // end condition
var head = items[0] // item to operate
head = head.toUpperCase() // perform action
var tail = items.slice(1) // next
return [head].concat(toUpperArray(tail)) // recursive step
}
toUpperArray(['hello', 'world']) // => ['HELLO', 'WORLD']
I don't understand how the "end condition" works. I think that conditional is looking for the items.length to be 0, but then it returns an empty array? I have tried running this by having it return nothing, which returns undefined thus adds undefined to the final array, but I am not sure why returning an empty array fixes this. I would expect the final item in the final array to be an empty array.
Also, I have never seen a conditional that didn't use curly braces. Is that significant?
When the array is empty. i.e. items.length == 0. The below condition is short form of != 0 because 0 is a false value in javascript, not of 0 should be true.
if (!items.length) return [];
This is because of concat functions which called on Array and with an Array as argument produces an Array as result. Basically you can see it in this way:
the upper array of an empty array is an empty array (base case)
the upper array of an array with at least one element (think of it as element,[array]) is element.toUpperCase() concatenated with the trailing part of the array through the recursive call (recursive step)
Basically you have an array data = [e1, e2, ..., en] and a function f(x). You want to return [f(e1), f(e2), ..., f(en)] so you basically apply the function on the first element on the array and concatenate the result with the value returned from the same recursive function on the same array without the first element.
When the items.length will be eqal to 0 (false), the function will return an empty array and will go up the recursion call stack. Here is a couple way we could have written this condition:
if(!items.length) //true
if(items.length == 0) //true
if(items.length == false) //true
For the conditions without curly braces. It does the same thing except that it only takes the current line or the next line as the "content" of your condition:
if(randomBoolean)
console.log('this is executed');
console.log('this is always executed');
In that example if the randomBoolean variable is true the output will be:
this is executed
this is always executed
If the randomBoolean variable is false, you will see:
this is always executed
function toUpperArray(items) {
if (!items.length) return [] // end condition
var head = items[0] // item to operate
head = head.toUpperCase() // perform action
var tail = items.slice(1) // next
return [head].concat(toUpperArray(tail)) // recursive step
}
Line 1: If there are no items left in the array,
return an array with nothing in it.
Line 2: Take the first item of the given array
Line 3: transform it into upper-case letter
Line 4: create a new array without the just transformed item
Line 5: call the function with the remaining array, concat it with the transformed item and return.
What happens? lets take your example:
[ X, Y ] means, you have an array with array[0] = X, array[1] = Y. So you have items[0] = 'hello', items[1] = 'world'.
The first call is transforming 'hello' to 'HELLO'.
The remaining array is ['world'].
then the function gets called again and transforms it to 'WORLD'.
Then it is called again, has no items and then it returns an empty array. This means the second call can return too by concating ['WORLD'] with [].
Then the first call can return by concating ['HELLO'] with ['WORLD'] which is ['HELLO', 'WORLD'].
It converts all the values in the array up to UPPERCASE.
Could use for loop but they basically just call the function again for the next array value.

Categories