Sign up ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free.

I was wondering what people think about using a reduce function vs loop for returning true if a condition exists.

Example:

var a = [1, 5, 7, 4, 2, 5, 3];

var greaterThan5 = a.reduce(function(prev, val) {
    return (prev || val > 5);
}, false);

vs

var greaterThan5 = false;
for(var i = 0; i < a.length; i++) {
    if(a[i] > 5) {
        greaterThan5 = true;
        break;
    }
}

vs

var i = 0;
var greaterThan5 = false;
while(!greaterThan5 && i < a.length) {
    greaterThan5 = (a[i] > 5);
    i++;
}

The for loop and while loop will exit when the condition is true, but I think the reduce syntax is easier to read and gives less room for run-time errors.

share|improve this question

closed as primarily opinion-based by Ixrec, gnat, MetaFight, MichaelT, durron597 Aug 15 at 18:55

Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise.If this question can be reworded to fit the rules in the help center, please edit the question.

1  
In terms of functional programming, most functional languages don't have for or while loops. Indeed they don't have any control structure syntax. Only functions. –  slebetman Aug 15 at 10:55

2 Answers 2

up vote 15 down vote accepted

First of all, why not use Array.prototype.some(), which seems to perfectly match what you're actually trying to do.

The some() method tests whether some element in the array passes the test implemented by the provided function.

Of course, that doesn't really answer your question: whether to use the for loop, or the call to Array.protoype.reduce()? Let me also try to answer that. The question is mostly regarding weighing performance against clarity of code.

For performance: measure, not just using random arrays, but using arrays that make sense in your project. No need in selecting a method that works fast on 1,000,000 element arrays, when all you need to process are arrays of up to 10 elements.

More importantly, only worry about performance when performance is an issue.

With respect to clarity. I actually think the explicit for-loop is more clear than the Array.prototype.reduce(). But, what matters most is, what the people on your team will find the most clear. If one of your team finds an explicit for-loop more clear, it's probably better to use that, if only because it uses a less advanced set of features.

share|improve this answer
1  
.reduce() offers an opportunity to expose colleagues to the greater set of tools - its also standard since 2011 or there about(s) so short of something like a necessity for that sort of legacy support - it could be novel given the argument spec. some() also accomplishes the novelty with the same service agreement, of course. love it. –  Brandt Solovij Aug 15 at 7:04
4  
I personally find reduce() unclear in this example because, as you point out, reduce() is not what the OP actually wants to do. some() definitely beats all of the above. –  Ixrec Aug 15 at 10:39
    
what the people on your time will find the most clear a bit hard to understand. Is time a typo for team? –  Caridorc Aug 15 at 11:02
1  
Also be aware of Array.prototype.every for the and version of the short-circuiting reduce. –  Darkhogg Aug 15 at 11:25
1  
@Caridorc: yes, it was a typo. Darkhogg corrected it now. –  Sjoerd Job Postmus Aug 15 at 13:40

For most functional languages, neither.

There is usually a reducing function which short circuts as you want it to.

In F# this is List.exists so you example would be

List.exists (fun x -> x > 5) a

In Haskell (with partial application of > to make a point free solution)

any (> 5) a
share|improve this answer
    
The above example could be written even shorter with the pointfree style as List.exists ((>)5) a –  Overly Excessive Aug 15 at 6:38
    
thank you. I found that javascript has the Array.prototype.some() function that does the same thing. –  Tony Brix Aug 15 at 6:40
    
@OverlyExcessive i dont think that will do what you think it will, that will bind the first argument of > to 5 i.e. you will be checking 5 > x –  jk. Aug 15 at 6:42
    
@jk Right, but if you reverse the comparison it will give the same results as the lambda. –  Overly Excessive Aug 15 at 6:46
    
@OverlyExcessive yes i take your point - added point free haskell version - as f# doesnt appeat to have away to do this without changing the operator i'd argue that it hurts readability there –  jk. Aug 15 at 7:22

Not the answer you're looking for? Browse other questions tagged or ask your own question.