Check if every element in array has a specfic value - javascript

I have an array with integers in it; and a function that returns a string. In this example, the function returns either 'solved' or 'unsolved', based on the fact if a specific task was done before or not.
Now I need a way to call my function with every array element as parameter and check if the function returns 'solved' for every element.
Small example with real values:
var array1 = [2,5,8]; // 2 is solved, 5 is solved, 8 is unsolved
var array2 = [2,5,6]; // every element is solved
if (Function returns solved for every element) {
// array2 would be accepted for this part
}
else {
// array1 would go in this branch
}

Array.prototype.every()
The every() method tests whether all elements in the array pass the test implemented by the provided function.
If you already have a function that returns a string (i.e. 'solved' or 'unsolved'), then you can simply convert that to a boolean inside the callback you supply to .every().
var array1 = [2, 5, 8]; // 2 is solved, 5 is solved, 8 is unsolved
var array2 = [2, 5, 6]; // every element is solved
function isSolvedString(operand) {
return operand < 8 ? 'solved' : 'unsolved';
}
function isSolved(current) {
return isSolvedString(current) === 'solved' ? true : false;
}
console.log(array1.every(isSolved)); // false
console.log(array2.every(isSolved)); // true

Related

filter and includes in array, how does that work?

I'm trying to understand how filter() and includes() work with arrays in javascript but english isn't my native language so I would really appreciate it if someone could explain the example below to me like I was 5:
const removeFromArray = function(...num) {
let array = num[0];
return array.filter(val => !num.includes(val))
};
This function takes an array and some other arguments then removes the other arguments from that array for example removeFromArray([1, 2, 3, 4], 3) should remove 3 and return [1,2,4]
How does this part work?
return array.filter(val => !num.includes(val))
Why the exclamation mark and also how do those two methods work together?
I think the key to understanding what is going on is the parameter(s) of the function, num. The code uses a nice trick that I have not encountered before. So, num is:
[[1, 2, 3, 4], 3];
a 1D array with TWO elements: [1, 2, 3, 4] at index 0, and 3 at index 1. As a result:
num.includes([1, 2, 3, 4]) // is true
num.includes(3) // is true
num.includes(anything-else) // is false
The
Array#includes
method determines whether an array includes a certain value among its
entries, returning true or false as appropriate.
In the simplest form, whenever a boolean expression is prefixed with !, the result of the expression is negated. For example:
!num.includes(3) // becomes false
The
Array#filter
method creates a new array with all elements that pass the test
implemented by the provided function.
Pass the test simply means return true.
Now we are ready to look at num[0].filter(val => !num.includes(val)). Or:
[1, 2, 3, 4].filter(val => !num.includes(val))
Please recall that ONLY 3 and [1, 2, 3, 4] return true to:
num.includes(val)
Hence of all the elements of num[0] or [1, 2, 3, 4] only 3 returns false to the negated expression:
!num.includes(val)
1, 2, and 4 return true or !false, meaning that they pass the test and hence will be returned by the function:
[1, 2, 4];
Please note that val => !num.includes(val) is a shorthand way of writing:
function( val ) {
return !num.includes(val);
}
const removeFromArray = function(...num) {
let array = num[0];
return array.filter(val => !num.includes(val))
};
console.log( removeFromArray([1, 2, 3, 4], 3) );
Rest parameters shouldn't be used like that, it should only be used for like values. So, the array should be accepted separately and only the numbers to remove should be accepted using rest (refer to the snippet below).
The includes() method determines whether an array includes a certain value among its entries, returning true or false as appropriate.
So, we simply filter out numbers that are not present in the itemsToRemove array.
const removeFromArray = (array, ...itemsToRemove) =>
array.filter((item) => !itemsToRemove.includes(item));
removeFromArray([1, 2, 3, 4], 3, 2);
! means "not". If something is falsy (null, 0, false, an empty string), then !something returns true. This leads to a really strange looking "cheat code" where you can convert any value to a boolean (i.e. truthy to true and falsy to false) via !!value. One exclamation point converts it to a boolean value that's true if value is falsy, then the second exclamation point changes true to false (or false to true)!
array.prototype.filter requires a function to be evaluated against each element and returns an array of only the elements where the supplied function returns a truthy value.
It might be easier to think of the following code that is nearly equivalent to yours...
const removeFromArray = function(array, ...valsToRemove) {
const isValToKeep = val => array.includes(val) === false;
return array.filter(isValToKeep)
};
The only difference in this code, besides being longer, is that the first argument won't be looked for within the first argument. Consider
const a1 = [1,2,3];
a1.push(a1); // appends itself as its last element
In your version, removeFromArray(a1, 2) would return [1, 3], but mine doesn't combine the first argument as one of the elements to look for and remove from the first argument, which is probably what most people would expect and be more performant, but would definitely have a different effect in the example returning [1, 3, a1], i.e. [1, 3, [1, 2, 3, [1, 2, 3, [1, 2, 3, [1, 2, 3, [1, 2, 3, [1, 2, 3, [...]]]]]]]]
This is a simple form to explain how to use filter
function isBigEnough(value) {
return value >= 10;
}
var filtered = [12, 5, 8, 130, 44].filter(isBigEnough);
// result is [12, 130, 44]
This example is from: https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
Lets start by rewriting this line:
Before
return array.filter(val => !num.includes(val))
after
const callback = val => {
return !num.includes(val)
}
const filteredArray = array.filter(callback);
return filteredArray
Now lets break and explain parts of this statement:
! num.includes(val)
includes method here will check if num has val in it. If num has val it will return true else it will return false. note the ! at the begining of the line ,that will change the value returned by includes to its opposite e.g if value returned is false it will change it to true if value returned is true it will change it to false.
array.filter(callback)
The filter method here will go through every element of the array and at each element it will ask whether to add that element to the filteredArray or not based on what is returned from the callback. If callback returns true(truthy) it will add it else it will not add it. The callback should only return true(truthy) or false(falsy).
example :
At index 0 of array the filter will ask did callback return true if it returned true the element at index 0 will be added to the filtered array. It will do the same for the rest of the elements.
How they work together:
array has [1,2,3,4] so array.filter(callback) will go over each element and call callback on each. Based on your function num has this [[1,2,3,4],3] so when val from array is 3 !num.includes(val) will return true but this ! will change it to false as a result callback will return false and 3 will not be included in the final array the filteredArray.
Hope a 5 year old can understand this explantion. You can now rewrite your function like this :
const removeFromArray = (array, ...numbersToRemove) => array.filter((number) => !numsToRemove.includes(number));

Javascript some() returns false on zero

I need to check if numbers exist in my array. Using the some() function I find that zero comes back false. It's a problem because I am working with a ton of different numbers and zero being one of them.
var array = [0, 1, 3, 4, 5];
var test = function(element) {
return 0;
};
console.log(array.some(test));
// expected output: true on 0 <-- getting false
// expected output: true on 1
// expected output: false on 20
In short how can I get 0 to return true?
the test function always returns zero.
var test = function(element) {
return element == 0
};
This way the function should work properly.
The test function should return true/false.
In your case you always return 0 which is evaluated to boolean false.
For what you're trying to implement, it might make more sense to use the .includes function, which tests whether an array includes a value:
var array = [0, 1, 3, 4, 5];
console.log(array.includes(0));
console.log(array.includes(1));
console.log(array.includes(2));
Though, .includes (along with all array iteration methods) is an O(N) process - if you need to carry out a bunch of tests for the same array, you might convert the array to a Set first, so that you can then use Set.has (which is generally O(1)):
var array = [0, 1, 3, 4, 5];
const set = new Set(array);
console.log(set.has(0));
console.log(set.has(1));
console.log(set.has(2));

Removing repeated values from array with multiple arguments

These are the full instructions for what I am trying to accomplish :
You will be provided with an initial array (the first argument in the destroyer function), followed by one or more arguments. Remove all elements from the initial array that are of the same value as these arguments.
This is the solution I have:
function destroyer(arr) {
var args = Array.prototype.slice.call(arguments);
args.slice(0,1);
return arr.filter(function(elements) {
return args.indexOf(element) === -1;
});
}
Keep in mind that there could be any number of arguments (not just 2 or 3).
The solution I have isn't working. What is wrong with my current solution and how can I fix it with an explanation?
Your solution is almost working.
The problems:
args.slice(0,1); does not modify the array (anyway this method just returns an array with the first element). Use args.shift() instead to remove the first element
function(elements) should be function(element) in the filter callback.
A working solution:
function destroyer(arr) {
var args = Array.prototype.slice.call(arguments);
args.shift();
return arr.filter(function(element) {
return args.indexOf(element) === -1;
});
}
console.log(destroyer([1, 2, 3, 5, 5], 1, 5)); // prints [2, 3]
Check the working demo.

I need some clarification on the program below. How does the "t" argument affect the program

The code works, I just have no idea how the "t" value becomes the number 4 in the second array. Any help will be greatly appreciated.
function diff(arr1, arr2) {
var newArr = arr1.concat(arr2);
function checkit(t) {
if (arr1.indexOf(t) === -1 || arr2.indexOf(t) === -1) {
return t;
}
}
return newArr.filter(checkit);
}
diff([1, 2, 3, 5], [1, 2, 3, 4, 5]);
Array filter() method creates a new array with all elements that pass the test implemented by the provided function in its argument.
In your case you are providing the checkit method to filter where it iterates through newArr. For each iteration t is the value present in newArr where you are basically checking whether t is present in both of arr1 and arr2 or not. If either of them do not have that element, you are returning back the element.
Here 4 is the value.
To make it more clear, I will break this into steps :
var newArr = arr1.concat(arr2);
Here after concat newArr becomes [1, 2, 3, 5, 1, 2, 3, 4, 5].
In the next step newArr.filter() method is called.
As per the filter() docs : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter filter() method filters out the elements from the invoked array that passes the required test as per the callback provided. Here the callback or the method is checkit().
In the checkit() method the t represents the value of an element in newArr. So in the if condition you are checking whether t is present in arr1 and arr2 or not.
Let's take the 1st element of newArr as an example. Now 1st element in newArr is 1. arr1.indexOf(1) would give you zero, because element 1 is present at the zeroth postion of arr1. Same happens with arr2. Now arr1.indexOf(1) === -1 would give you false and arr2.indexOf(1) === -1 would also give you false.
It will go on like this until you reach value 4 ie. the second last element in newArr. Here when you do arr1.indexOf(4), you will get -1 as the element 4 is not present in the arr1. So arr1.indexOf(1) === -1 would give you true. The if condition will get true and the current element t ie 4 will be returned.
Next as 5 is present in both the arrays the if condition won't get satisfied. Hence you are left with only 4 in your array.

Javascript: Why array variable assignment is behaving differently inside and outside this function?

For the life of me, I just can't figure out what I'm doing wrong here.
I'm trying to use both the reduce and concat array methods to take all of the values of a 2d array and combine them into a single value (basically condense them into a single array and then sum them up).
The problem that I keep running into is that when I try to make a for/loop to concat each array element, the argument that I'm passing into the function is not being recognized as an array, thus my call to .concat() is failing. I've placed a console.log() at the beginning of the function to see if the element is being recognized as the first array element in the 2d array, and it's coming up as "1"(?).
I tried another test outside of the function, and it logs as the actual array element. What am I doing wrong here? code below:
var arrays = [[1, 2, 3], [4, 5], [6]];
var myArray = arrays[0]; // Test
console.log(myArray); // Test
var flatArray = arrays.reduce(function(arrays)
{
console.log(arrays[0]); // Test
for (var i = 0; i < arrays.length - 1; i++)
{
arrays[0].concat(arrays[i+1]);
}
return arrays;
});
console.log(flatArray);
This is the output that I keep getting:
Array [ 1, 2, 3 ]
1
TypeError: arrays[0].concat is not a function
It's almost seems like array is being converted to a number-type when inside the function...?
You have an error in your code here:
var flatArray = arrays.reduce(function(param) {})
that param will be an element of your arrays vector.
Check this https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
You are using .reduce() incorrectly and you don't even need to use it to flatten an array. You can just do this:
var flatArray = [].concat.apply([],arrays);
Working demo: http://jsfiddle.net/jfriend00/wfjyfp42/
To understand .reduce(), the callback you pass it gets four arguments (see MDN reference). The first two arguments are important in using .reduce() correctly:
callback(previousValue, currentValue, index, array)
The previousValue is the accumulated value so far in the reduction. The currentValue is the next element of the array that is being iterated. The last two arguments do not need to be used if not needed.
Your code is only using the previousValue so it is never looking at the next item in the array as passed in by .reduce().
You could make a solution work using .reduce() like this:
var flatArray = arrays.reduce(function(previousValue, currentValue) {
return previousValue.concat(currentValue);
}, []);
Working demo: http://jsfiddle.net/jfriend00/2doohfc5/
Reduce performs an operation on two elements.
var sum = [[1, 2, 3], [4, 5], [6]].reduce(function(a, b) {
return a.concat(b);
}).reduce(function(a, b) {
return a + b;
});

Categories