Where to use additional condition when using Array methods - javascript

I was trying to solve the following question:
Write a function that returns true if all array elements are true. Use reduce
The is the solution I made up
function allTrue(values) {
if ( values[0] === false) return false
if (values.length === 0) return true
let result = values.reduce( (final, value) => final = value === true, true)
return result ? true : false
}
My question is, whether it is possible to move the external conditions into the reduce method's body or not.
In other words, if I was required to use a single reduce method to solve it, can I implement it?
I tried manipulating the final in the reduce, but it is modified later in next iterations
For instance the following test should return false but returns true
allTrue([false, true])
Any explanation would be appreciated, thank you

The reason your code doesn't work is that the reduce only returns the result of the comparison of the last element in the array with true. Since the last element in [false, true] is true, it returns true.
Note that your code is overly complex, you have already effectively included your conditions in the reduce (giving an initial value of true means that a zero-length array will return true). Your one issue is that the code in the reduce is incorrect, you should be checking whether all the previous values are true as well as the current one by and'ing the current value with the and of all the previous values:
const allTrue = (values) => values.reduce((curr, value) => curr && value, true);
console.log(allTrue([]));
console.log(allTrue([true]));
console.log(allTrue([false]));
console.log(allTrue([true, true, true]));
console.log(allTrue([false, true]));

I think this can be help:
function allTrue(values) {
return values.reduce((final, value) => final && value)
}

We can use every as well to find the solution to this. Below is the snippet for both every as well as reduce
var allTrue_Every = (arr) => arr.every(d => d == true)
console.log(allTrue_Every([true, true]))
console.log(allTrue_Every([true, false]))
var allTrue_Reduce = (arr) => arr.reduce((r, d) => r && d, true)
console.log(allTrue_Reduce([true, true]))
console.log(allTrue_Reduce([true, false]))

Related

How to return a boolean true if all the values in an array are true (strings) and if one of the value is false(string) stop checking using Javascript

I have an array
var myarr = ["true","false","true"];
I want the above to return false of boolean type.
var myarr = ["true","true","true"];
I want the above to return true of boolean type.
Can someone please help with what's the most efficient way to achieve this?.
Is it best to first convert the string to boolean in another array and then use .every()?.
Please advise. Thank You.
Check your answer out here, you'll certainly get a more in-depth answer here: Check if all values in array are true, then return a true boolean statement (javascript)
let arr1 = ['true', 'false', 'true'],
arr2 = ['true', 'true', 'true'];
let checker = arr => arr.every(v => v === 'true');
console.log(checker(arr1));
console.log(checker(arr2));
Check that .every value is 'true'.
return myarr.every(val => val === 'true');
To stop processing if a "false" string is encountered, use Array.prototype.some
const allTrue = arr => !arr.some(entry => entry === 'false');
console.log("expect false true:");
console.log( allTrue(["true","false","true"]) );
console.log( allTrue(["true","true","true"]) );
If you need to check for 'true' strings, use a !== operator in the some argument:
const allTrue = arr => !arr.some(entry => entry !== 'true');
You can use like below, because Array.every iterates every element present in an array even it has false present in it.
const result = myarr.includes('false'); // true
const result2 = myarr.some((v) => v === 'false'); // true

Shortest way to "or" a list of booleans in javascript

I have a list of booleans. I want to apply || ("or") on each of them, and get the result. (So, a new boolean.)
The list has no fixed length, so I can't simply write the code as value = l[0] || ... l[length-1]. (It would also be ugly for long lists.)
My approach:
let index = 0;
let value = true;
while(index < list.length && value == value || list[index]) {
index += 1;
}
I guess that this is possible as one statement. How?
You could use .includes, which checks if an Array includes a value, and returns true / false
const list = [true, true, true, true, false];
// Checks if list contains the Boolean True
const value = list.includes(true);
console.log(value);
One option is to use .some:
const value = list.some(Boolean);
const list = [false, false, false, true, false];
const value = list.some(Boolean);
console.log(value);
const list = [false, false, false, false, false];
const value = list.some(Boolean);
console.log(value);
This is a classic use case for reduce:
value = list.reduce((a, b) => a || b, false);
(Note the starting accumulator value should be false - using true as you are, the result will always be true!)
In the general case, this is exactly what Array.prototype.reduce is for:
list.reduce((previousValue, currentValue) => previousValue || currentValue)
reduce (or fold as it is called in some other languages) is a general method of iteration which means that anything you can do with a loop, you can also do with reduce. What reduce does, is use a binary operation to "fold" all elements of a collection into a new value. In this case, it is a rather simple operation, and the result type is the same type as the elements, but that doesn't have to be the case: the result type can be different than the element type, and the result type can be arbitrarily complex (it can even be again a collection).
You can think of reduce as replacing the comma in an array with a binary operator. In other words, if you have
const arr = [a, b, c, d, e, f, g];
then
arr.reduce((accumulator, element) => accumulator + element)
will compute
a + b + c + d + e + f + g
However, because reduce is a general method, it doesn't convey much meaning. There are more specialized methods that cannot do "everything", but using those methods tells the reader more about what is going on in your code. So, for example, you can use reduce to transform each element, but you should rather use Array.prototype.map for that.
Note that your specific example has some specific properties: since OR-ing a bunch of values together is only false if every single value is false, or in other words, is true if at least one value is true, all we need to check is if there is some element that is true.
And there is a specific method for checking whether some element has a specific property: Array.prototype.some:
list.some(el => el)
In this case, the property is actually just the identity function. Alternatively, you can use the Boolean constructor, which acts as the identity function for booleans:
list.some(Boolean)
you can also use Array.prototype.includes to check if the list includes at least one true value:
list.includes(true)

Am I using filter right? I don't know why this solution works

I'm going through FCC basic algorithms right now, and while I passed the exercise, I'm not fully understanding why it works, as when I change things to how I think they should be it doesn't work, but when I change things so they look wrong to me it still works.
For instance, I change true to false, and it still works, or I just type true, and it still works, or I just say return value, and it works. Does filter automatically remove falsy values?
Here is my code. My original code that didn't work said if (value === true).
function bouncer(arr) {
let x = arr.filter(value => {
if (value !== true)
return value;
})
console.log(x);
return x;
}
bouncer([7, "ate", "", false, 9]);
Remove all falsy values from an array.
Falsy values in JavaScript are false, null, 0, "", undefined, and NaN.
UPDATE
Thanks for all the answers, they were all super helpful in clearing up my confusion.
function bouncer(arr) {
let x = arr.filter(ages => {
return ages;
})
return(x);
}
bouncer([7, "ate", "", false, 9]);
This is the solution I ended up re-writing, and now understand why I did what I did.
Your callback,
if (value !== true)
return value;
is equivalent to just
return value;
in your case because none of the elements in your array are true, so value !== true always holds.
If you change it to
if (value !== false)
return value;
it still executes return value; for most array elements. The only exception is false, for which your function returns undefined (because no explicit return statement is executed). undefined is falsy, so it is treated the same as return false by filter (because filter only cares whether the callback returned a true or falsy value). So in the end not returning a value if the element is false is the same as return value.
On the other hand, if you change it to
if (value === true)
return value;
then your callback would return true if the current element is true and return undefined for any other value. The net effect is removing all elements that are not true (which in your case is all elements because your input array does not contain true).
If you want to remove falsy values, you can simply say
arr.filter(value => { return value; })
// or:
arr.filter(value => value)
because you're using the value itself as the condition: Anything that looks falsy is removed by filter; anything that looks true is kept.
If you find this confusing, perhaps looking at this custom (and simplified) filter implementation clears things up:
function my_filter(arr, fn) {
var results = [];
for (var i = 0; i < arr.length; i++) {
if (fn(arr[i])) {
results.push(arr[i]);
}
}
return results;
}
// Usage would be something like:
console.log(my_filter([7, "ate", "", false, 9], value => value));
If your purpose is to return an array that only retains the truthy values, then do this:
.filter(Boolean)
In your callback to filter you don't always return a value, and if you don't, that means the corresponding value will not be retained. Furthermore, with operators like !== and === you are doing a strict comparison. So value === true will only match true, not any other truthy value. Similarly, value !== true will still match some truthy values (that are not true).
filter iterates over your array. In each element iteration the callback is called.
If you return a "truthy" value in the callback that element is kept in the resulting Array, otherwise it's not.
Your confusion stems from the fact that you think you need to return the value argument in some way. You don't.
Look at this example:
var animals = ['dog', 'dog', 'cat', 'cat']
var cats = animals.filter(value => {
if (value === 'cat') {
return true
} else {
return false
}
})
console.log(cats)
Of course the above can be simplified to this:
var animals = ['dog', 'dog', 'cat', 'cat']
var cats = animals.filter(value => {
return value === 'cat'
})
console.log(cats)
That's just it.

Every function with Object.values not working

I have an object and I need to check if all the values are true.
{
condition1: true,
condition2: true,
condition3: false
}
Ive used Object.value to get an array of the true and false values. However I cant seem to get the every function to work, it always returns true.
const test = Object.values(equipmentSelection)
.every((element) => {
if (element = true) return true;
});
Just return the element without using conditional check, you can do like this
const test = Object.values(equipmentSelection)
.every(element => element)
});
You are using an assignment operator = instead of a logical == or === operator. So you are basically setting element to be equal to true and then use this same value (true) as the condition of if. So the if condition is always true and thus true is returned for each element in the array.
Since element is of type boolean, you don't need the if statement, just use its value:
.every(element => element);
You can do this.
const test = Object.values(equipmentSelection)
.every(element => element===true);
And like others have said,
.every( element => element);
Will return the elements value which is with true or false and that’s what you will get with the comparisons.

Check array for multiple values in specific order

I have this array (below) and I'm trying to check if it has specific values.
var a = [ true, "lipsum" ];
What I need to do, is to check if a[0] is true and if a[1] is "lipsum"
I could check both values separately:
a[0] === true && a[1] === 'lipsum' // true
...to shorten the code a bit, I tried to do this:
a === [ true, 'lipsum'] // false
Why is this code example above false and is there another way to achieve what I'm trying to do?
I could do this:
a.join() === 'true,lipsum' // true
though I can't help but feel that there is a better way..?
jsfiddle
For only two elements to check the straightforward way seems best, but I assume you want to do this for maintenance reasons because eventually you may have several conditions to check (not just two). If so, you can do something like the following, which seems verbose for only two conditions, but as you start adding more it would be more reasonable, so here's an example with 5 conditions to check:
// set a constant somewhere for your truth condition
var COND = [1, 'a', 5, 'b', 0];
// check `a` against the constant array using `every` (Thanks Bergi)
if (a.every(function(v, i){ return COND[i] === v; })) {
// all array elements the same
}
Each array is a separate object, so the equality operator cannot be used to compare them. Assuming that you have a strict comparison of known arguments to do, the first method you use is the best.
If you have another array of arguments that the original array must contain, you must use a loop, although you could abstract it:
Array.prototype.contains = function (array) {
for (var x = 0; x < array.length; x++) {
if (this.length < x || this[x] !== array[x]) {
return false;
}
}
return true;
}
http://jsfiddle.net/q5DvG/1/

Categories

Resources