Getting boolean result of array - javascript

let's say I have an array with n elements of boolean values.
var a = [true,false,true,true,false]
How do I do the OR product of the array.
SO that var result = (true || false || true || true || false) = true

You can use some :
var result = a.some(function(value) {
return value;
});

All these suggestions are far too complex. Just keep it simple. If you want OR then you just need to check if the array contains a single true value:
var result = a.indexOf(true) != -1;
Similarly, if you wanted AND you could just check if it doesn't contain false value, also if you want an empty array to result in false then check the length too:
var result = a.length > 0 && a.indexOf(false) == -1;
Here is a working example, that shows both OR and AND in action.
And here is a performance review of all the current answers, where you can see keeping it simple like this is much quicker than the other suggestions (well, Nina is close to mine as her answer is similar, but less readable IMO). Of course you can argue performance isn't going to be noticed with something like this, but still better to use the fastest method anyway.

Short in one command.
!!~a.indexOf(true)

You may iterate over the array and find it.
var a = [false,false,false,false,false]
var result = a[0];
for(i=0;i<a.length;i++){
result = result || a[i]
}
alert(result);
I hope this would help you
https://jsfiddle.net/0yhhvhu7/3/

From MDN
The Array.prototype.reduce() method applies a function against an accumulator and each value of the array (from left-to-right) to reduce it to a single value.
a.reduce(function(prev, curr) {
return prev || curr;
});

Related

Returning null or nothing instead of empty array with array.filter

Is there a vanilla js way of returning null (or nothing) instead of an empty array[]
from Array.prototype.filter when no elements are found?
Some context:
let arr = [1,2,3,1,1]
let itemsFound = arr.filter(e=> e===6)
if(itemsFound){ // always true, []===true
// do something
}
The if will always evaluate to true as filter returns an empty array[].
And an empty array is 'true' in javascript. Of course I can do,
if(itemsFound.length > 0){
// do something
}
But I think just, if(itemsFound){} is neater.
The answer would not require additional js libraries.
Additional context
Coming from an OO background, I found it quite funky that objects and functions
could be treated like Boolean. But felt it was intuitive after getting used to it.
There are times that I would forget that Array.filter returns an empty array [] when no elements are found. And [] === true. This causes unnecessary bugs.
As with the answers and feedback received of now, I don't think this question can be answered except with a new implementation of Array.filter.
With that said, the accepted answer is the closest to what I have in mind.
you can do something like this, if you just want to check if it exists or not
let arr = [1,2,3,1,1]
let itemsFound = arr.filter(e=> e===6).length
console.log(itemsFound);
if(itemsFound){ // always true
// do something
}
or something like this
let arr = [1,2,3,1,1]
let itemsFound = arr.filter(e=> e===6)
itemsFound = (itemsFound.length > 0 ? itemsFound : false);
console.log(itemsFound)
if(itemsFound){ // always true
// do something
}
Or something like this
Array.prototype.isEmpty = function(){
return this.length == 0;
}
let arr = [1,2,3,1,1];
arr.isEmpty();
let itemsFound = arr.filter(e=> e===6)
if(itemsFound.isEmpty()){ // always true
// do something
console.log('OK');
}
You could use the length property of an array and take the value as truthy/falsy value for the condition.
function getValues(array) {
const result = array.filter(e => e === 6);
return result.length ? result : null;
}
console.log(getValues([1, 2, 3, 1, 1]));

Simple way to force javascript to always return an array

I stumbled upon the YQL API to query for WOEIDs for use in Twitter, but I can see the output is not always in array. The API returns an object and I'm interested in value of response.query.results which returns the following:
if there are no results, it returns null
if there is only one result, it returns an object
if the are multiple results, it returns an array
I want the result to always be an array. I can solve this by checking the result using the following code:
var count = response.query.count;
if(count === 0) {
return [];
} else if(count === 1) {
var arr = [];
arr.push(response.query.results);
return arr;
} else {
return response.query.results;
}
Is there a javascript or lodash function that can simplify the above code? It seems _.forEach and _.toArray will treat each property as an object if provided with a single object.
You could use Array#concat with a default array if response.query.results is falsy.
return [].concat(response.query.results || []);
By having zero as value for response.query.results, you could take the Nullish coalescing operator ?? instead of logical OR ||, which repects all values without undefoned or null
return [].concat(response.query.results ?? []);
https://lodash.com/docs/4.17.4#concat
_.concat([],response.query.results);
would also do it.
but as #Brian pointed out, we need to handle null being equivalent to [] so you can add
_.concat([],_.isNull(response.query.results)?[]:response.query.results);
note that this is more correct because it will work for results with falsey values (like 0 and false etc)
in general, lodash is more robust than built in javascript. this usually works in your favour. one place this can trip you up is if results was a string (which is an array of characters)
https://github.com/lodash/lodash/blob/4.17.4/lodash.js#L6928
function concat() {
var length = arguments.length;
if (!length) {
return [];
}
var args = Array(length - 1),
array = arguments[0],
index = length;
while (index--) {
args[index - 1] = arguments[index];
}
return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));
}
Similar to Tom's answer above, the lodash function castArray (https://lodash.com/docs/4.17.15#castArray), introduced in Lodash v4.4, could also work for this. It has the marginal benefit that its intent is slightly more clear that [].concat(x)
const _ = require('lodash')
_.castArray(null) // [null]
_.castArray({a:1}) // [{a:1}]
_.castArray([{a:1},{a:2}] // [{a:1},{a:2}]
To deal with the null, considerations are similar to answers above, depending on how you want to handle unexpected values. A ternary with _.isNull would work, or else ?? is useful, e.g.:
const castArrayRemovingNullUndef = x => _.castArray(x ?? [])
const castArrayRemovingNull = x => _.castArray(_.isNull(x) ? [] :x)
_.castArrayRemovingNull(null) // []
_.castArrayRemovingNull({a:1}) // [{a:1}]
_.castArrayRemovingNull([{a:1},{a:2}] // [{a:1},{a:2}]

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/

counting object properties with underscore.js

So I'm trying to think of a better way to do this with underscore:
state.attributes = _.reduce(list, function(memo, item){
memo['neighborhood'] = (memo['neighborhood'] || []);
var isNew = true;
_.each(memo['neighborhood'], function(hood){
if (hood.name === item.data.neighborhood) {
hood.count++; isNew=false;
}
});
if(isNew){
memo['neighborhood'].push({name:item.data.neighborhood, count:1});
}
return memo;
});
I would like to combine the various names of the list into a list of unique names with a count of how many times each unique name occurs. It seems like exactly the kind of problem underscore was designed to solve, yet the best solution I could think of seems less than elegant.
I'm not an underscore.js user, but I guess _.groupBy() suits this scenario:
var attributes = _.groupBy(list, function (item) {
return item.data.neighborhood
})
It doesn't returns an array in the exact way you want, but it contains all the information you need. So you have in attributes["foo"] all the items that have "foo" as neighborhood value property, and therefore in attributes["foo"].length the count of them.
Maybe there is a better underscore.js way, but you can already apply other optimizations:
Instead of using an array to keep track of the name and the count, use a name: count map. This can be easily done with an object:
state.attributes = _.reduce(list, function(memo, item){
var n = item.data.neighborhood;
memo['neighborhood'] = (memo['neighborhood'] || {});
memo['neighborhood'][n] = memo['neighborhood'][n] + 1 || 1;
return memo;
});
This works, because if item.data.neighborhood is not in the list yet, memo['neighborhood'][item.data.neighborhood] will return undefined and undefined + 1 returns NaN.
Since NaN evaluates to false, the expression NaN || 1 will result in 1.

How can I check JavaScript arrays for empty strings?

I need to check if array contains at least one empty elements. If any of the one element is empty then it will return false.
Example:
var my_arr = new Array();
my_arr[0] = "";
my_arr[1] = " hi ";
my_arr[2] = "";
The 0th and 2nd array elements are "empty".
You can check by looping through the array with a simple for, like this:
function NoneEmpty(arr) {
for(var i=0; i<arr.length; i++) {
if(arr[i] === "") return false;
}
return true;
}
You can give it a try here, the reason we're not using .indexOf() here is lack of support in IE, otherwise it'd be even simpler like this:
function NoneEmpty(arr) {
return arr.indexOf("") === -1;
}
But alas, IE doesn't support this function on arrays, at least not yet.
You have to check in through loop.
function checkArray(my_arr){
for(var i=0;i<my_arr.length;i++){
if(my_arr[i] === "")
return false;
}
return true;
}
You can try jQuery.inArray() function:
return jQuery.inArray("", my_arr)
Using a "higher order function" like filter instead of looping can sometimes make for faster, safer, and more readable code. Here, you could filter the array to remove items that are not the empty string, then check the length of the resultant array.
Basic JavaScript
var my_arr = ["", "hi", ""]
// only keep items that are the empty string
new_arr = my_arr.filter(function(item) {
return item === ""
})
// if filtered array is not empty, there are empty strings
console.log(new_arr);
console.log(new_arr.length === 0);
Modern Javascript: One-liner
var my_arr = ["", "hi", ""]
var result = my_arr.filter(item => item === "").length === 0
console.log(result);
A note about performance
Looping is likely faster in this case, since you can stop looping as soon as you find an empty string. I might still choose to use filter for code succinctness and readability, but either strategy is defensible.
If you needed to loop over all the elements in the array, however-- perhaps to check if every item is the empty string-- filter would likely be much faster than a for loop!
Nowadays we can use Array.includes
my_arr.includes("")
Returns a Boolean
You could do a simple help method for this:
function hasEmptyValues(ary) {
var l = ary.length,
i = 0;
for (i = 0; i < l; i += 1) {
if (!ary[i]) {
return false;
}
}
return true;
}
//check for empty
var isEmpty = hasEmptyValues(myArray);
EDIT: This checks for false, undefined, NaN, null, "" and 0.
EDIT2: Misread the true/false expectation.
..fredrik
function containsEmpty(a) {
return [].concat(a).sort().reverse().pop() === "";
}
alert(containsEmpty(['1','','qwerty','100'])); // true
alert(containsEmpty(['1','2','qwerty','100'])); // false
my_arr.includes("")
This returned undefined instead of a boolean value so here's an alternative.
function checkEmptyString(item){
if (item.trim().length > 0) return false;
else return true;
};
function checkIfArrayContainsEmptyString(array) {
const containsEmptyString = array.some(checkEmptyString);
return containsEmptyString;
};
console.log(checkIfArrayContainsEmptyString(["","hey","","this","is","my","solution"]))
// *returns true*
console.log(checkIfArrayContainsEmptyString(["yay","it","works"]))
// *returns false*
yourArray.join('').length > 0
Join your array without any space in between and check for its length. If the length, turns out to be greater than zero that means array was not empty. If length is less than or equal to zero, then array was empty.
I see in your comments beneath the question that the code example you give is PHP, so I was wondering if you were actually going for the PHP one? In PHP it would be:
function hasEmpty($array)
{
foreach($array as $bit)
{
if(empty($bit)) return true;
}
return false;
}
Otherwise if you actually did need JavaScript, I refer to Nick Craver's answer
Just do a len(my_arr[i]) == 0; inside a loop to check if string is empty or not.
var containsEmpty = !my_arr.some(function(e){return (!e || 0 === e.length);});
This checks for 0, false, undefined, "" and NaN.
It's also a one liner and works for IE 9 and greater.
One line solution to check if string have empty element
let emptyStrings = strArray.filter(str => str.trim().length <= 0);
let strArray = ['str1', '', 'str2', ' ', 'str3', ' ']
let emptyStrings = strArray.filter(str => str.trim().length <= 0);
console.log(emptyStrings)
One line solution to get non-empty strings from an array
let nonEmptyStrings = strArray.filter(str => str.trim().length > 0);
let strArray = ['str1', '', 'str2', ' ', 'str3', ' ']
let nonEmptyStrings = strArray.filter(str => str.trim().length > 0);
console.log(nonEmptyStrings)
If you only care about empty strings then this will do it:
const arr = ["hi","hello","","jj"]
('' in arr) //returns false
the last line checks if an empty string was found in the array.
I don't know if this is the most performant way, but here's a one liner in ES2015+:
// true if not empty strings
// false if there are empty strings
my_arr.filter(x => x).length === my_arr.length
The .filter(x => x) will return all the elements of the array that are not empty nor undefined. You then compare the length of the original array. If they are different, that means that the array contains empty strings.
You have to check in through the array of some functions.
if isEmptyValue is true that means the array has an empty string otherwise not.
const arr=['A','B','','D'];
const isEmptyValue = arr.some(item => item.trim() === '');
console.log(isEmptyValue)
array.includes("") works just fine.
Let a = ["content1", "" , "content2"];
console.log(a.includes(""));
//Output in console
true

Categories

Resources