3

Is there a smart way to find out if there are at least two values greater than 0 in an array and return true? And false in the opposite case?
(hypothetical and wrong example using some):

const a = [9, 1, 0];
const b = [0, 0, 0];
const c = [5, 0, 0];

const cond = (el) => el > 0 && somethingElseMaybe;

console.log(a.some(cond)); // print true
console.log(b.some(cond)); // print false
console.log(c.some(cond)); // print false


5
  • 2
    you mean, other than iterating through the array until you get 2 values > 0 - or sorting the array in decreasing order and check the first two element? Commented Feb 17, 2020 at 13:11
  • Please either define "fast and elegant" or remove it altogether. Commented Feb 17, 2020 at 13:11
  • 1
    array.filter(x => x > 0).length >= 2; (developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…) Commented Feb 17, 2020 at 13:12
  • 1
    Most often, "performant" and "elegant" are mutual exclusive. An elegant solution (less code) is slow and memory consuming, a performant solution (a lot of ugly code) is fast an less memory-consuming. Pick the latter, if the arrays are really big, pick the former, if there really are only three members in the array, and not too many arrays to handle. Commented Feb 17, 2020 at 13:20
  • no, there is no elegance in this kind of coding problem Commented Feb 17, 2020 at 13:21

6 Answers 6

8

Use filter() to remove values below zero and then check if the length of resulting array is greater than or equal to two

const twoGreaterThanZero = arr => arr.filter(x => x > 0).length >= 2;

console.log(twoGreaterThanZero([9, 1, 0])) //true
console.log(twoGreaterThanZero([0, 0, 0])) //false
console.log(twoGreaterThanZero([5, 0, 0])) //false

Sign up to request clarification or add additional context in comments.

8 Comments

Good answer, same as what I put in the comments. Not sure why someone down-voted. But then again most times you never do. +1.
Downvoter please comment and point out if there is any mistake in the answer?
use dynamic values instead of hard integer array values.
@MaheerAli I'd guess the downvote is because this will iterate the whole array even if you'd find the answer in the beginning. Not that it would matter in most cases.
I downvoted for the above reason.
|
5

To avoid wasted effort, you should stop the checking as soon as the condition is met. I think this meets your requirement.

function twoGreaterThanZero(arr) { 
    let counter = 0
    for(let x of arr) {
        if(x > 0 && (++counter > 1)) return true
    }
    return false
}

const a = [9, 1, 0]
const b = [0, 0, 0]
const c = [5, 0, 0]

console.log(twoGreaterThanZero(a)) // print true
console.log(twoGreaterThanZero(b)) // print false
console.log(twoGreaterThanZero(c)) // print false

1 Comment

Deleted my comment as it was addressed, +1
2

If you don't want to iterate over the entire array you can use a loop and break out of it early once your condition is satisfied. I think the answer that uses filter is more elegant, but if you're list is insanely large you might see a benefit from not iterating the entire thing.

I broke this function into it's basic parts and created a curried version.

The question is "are there 2 or more values greater than 0 in the array". But it can be boiled down to "are there X or more values that pass comparator"?

const a = [9, 1, 0];
const b = [0, 0, 0];
const c = [5, 0, 0];

const quantityCompare = compare => quantity => arr => {
  let count = 0;
  for (let i = 0; i < arr.length; i += 1) {
    if (compare(arr[i])) count += 1;
    if (count >= quantity) return true;
  }
  return false;
};

const twoElementsGreaterThanZero = quantityCompare(x => x > 0)(2);

console.log(twoElementsGreaterThanZero(a)); // true
console.log(twoElementsGreaterThanZero(b)); // false
console.log(twoElementsGreaterThanZero(c)); // false

One more for fun, you can use Array.some (an Array.forEach you can break out of) instead of the for loop:

const a = [9, 1, 0];
const b = [0, 0, 0];
const c = [5, 0, 0];

const quantityCompare = compare => quantity => arr => {
  let count = 0;
  return arr.some(el => {
    if (compare(el)) count += 1;
    if (count >= quantity) return true;
  })
}

const twoElementsGreaterThanZero = quantityCompare(x => x > 0)(2);

console.log(twoElementsGreaterThanZero(a)); // true
console.log(twoElementsGreaterThanZero(b)); // false
console.log(twoElementsGreaterThanZero(c)); // false

2 Comments

Using some is a neat hack, but I think I'd be surprised to see it used this way in a production codebase.
I agree, I included it because I found it neat as well. I don't think using some improves anything here, and in fact makes things less straight forward since it's not a very common array function imo.
1

If you are in a situation where doing things like this is frequently necessary, you can always create your own facility for producing predicate functions. In this case, you could start with a master function to create functions that return true or false if an array contains a minimum number of values that satisfy a condition:

function minimumSatisfy(condition, minimum) {
  return function(array) {
    for (var i = 0, c = 0; i < array.length && c < minimum; i++) {
      if (condition(array[i]))
        c++;
    }
    return c >= minimum;
  }
}

To use that for checking your particular case, use it to make a specific function:

let twoGtZero = minimumSatisfy(v => v > 0, 2);

Now you can test any array with that predicate:

if (twoGtZero(someArray)) {
  // ...
}

Of course if you've only got one place in your code that requires such a test, it would be silly to do this.

Comments

0

Try that

var a = [9, 1, 0]
var b = [0, 0, 0]
var c = [5, 0, 0]

function atLeastTwoEntries(arr, entrie) {
  return arr.indexOf(entrie) !== arr.lastIndexOf(entrie)
}

console.log(atLeastTwoEntries(a, 0))
console.log(atLeastTwoEntries(b, 0))
console.log(atLeastTwoEntries(c, 0))

4 Comments

this one is interesting
but the question is about 2 values greater than 0 not equal to zero.
This computes something different than what the question asked. This tells whether a particular value appears at least twice in an array, which is different.
I agree, my bad
-1

Try this,

console.log(a.filter(s => s > 0).length >= 2); // print true
console.log(b.filter(s => s > 0).length >= 2); // print false
console.log(c.filter(s => s > 0).length >= 2); // print false

5 Comments

at least two values greater than 0
I think I have rectified the bug. : ) Thanks for pointing this.
greater than is not greater than or equal to ... change >= to > and your answer is exactly the same as the first answer
Opsss, In a hurry made mistakes..
should've just copied the first answer that had it right the first time :p

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.