loading...

re: 5 Programming Patterns I Like VIEW POST

FULL DISCUSSION
 

3. One loop two arrays

Is reduce really necessary here? Wouldn't it be so much clearer to do this with a forEach?

const exampleValues = [2, 15, 8, 23, 1, 32];
const truthyValues = [];
const falseyValues = [];
exampleValues.forEach(exampleValue => {
        if (exampleValue > 10) {
            truthyValues.push(exampleValue);
        } else {
            falseyValues.push(exampleValue);
        }
});

5. Nested ternaries

The same flow you used in the ternaries can be applied to the if statements:

let result = null;
if (!conditionA) {
    result = "Not A";
} else if (conditionB) {
    result = "A & B";
} else {
    result = "A";
}

And if you used the same flow as in your if statements but with ternaries, they'd also look weird:

const result = conditionA
    : (
        conditionB
        : "A & B"
        ? "A"
    )
    ? "Not A";

Also, I find ternaries formatting to be more readable this way:

const result =
    !conditionA ? "Not A"
    : conditionB ? "A & B"
    : "A";
 

HA! I posted the almost the exact same else-if logic before realizing you had!

 

I think reduce is nicer because it's always clear that an Array.reduce constructs "something" from an array. The whole statement includes everything you need to know (i.e. the final argument is the base value) as opposed to declaring the arrays before the loop. No need to look outside the reduce for answers since it's all there.

Reduce can be a little intimidating in the beginning but once you get the hang of it it's wonderful and makes a lot of sense.

 

So it's better because you can put it in a single statement, even though you now have to address the arrays as array[0] and array[1] instead of by name?

You don't! You could actually do this instead:

const [truthyValues, falseyValues] = exampleValues.reduce(([truthyValues, falseyValues], exampleValue) => {
  if (exampleValue > 10) {
    return [[...truthyValues, exampleValue], falseyValues];
  }

   return [truthyValues, [...falseyValues, exampleValue]];
}, [[], []]);

I've spread the array in the return statement because I wasn't too fond of the push along with having to return the two arrays.

Another one, using an object instead of two arrays would be:

const { truthyValues, falseyValues } = exampleValues.reduce((result, exampleValue) => {
  if (exampleValue > 10) {
    result.truthyValues.push(exampleValue)
  } else {
    result.falseyValues.push(exampleValue)
  }

   return result
}, { truthyValues: [], falseyValues: []});

Which in my opinion is probably the easiest one to read.

I've spread the array in the return statement because I wasn't too fond of the push along with having to return the two arrays.

Which is how reduce is meant to be used, and why it is needed in functional languages that deal with immutable data. Otherwise you are just abusing it as a loop construct to feel functional.

But I wouldn't recommend this style in Javascript, because arrays are not linked lists and this becomes O(n2).

I don't have a computer science background so what you're referring to is not something I can easily relate to. I have a vague idea of the concept of linked lists, but I don't understand the big O notation (entirely new concept to me).

Do you mean that it's less performant than needed? Because I'm creating a new array which contains two arrays both of which will have to be looped due to using the spread operator as opposed to a push (which would not need to loop the whole array)?

Sorry if I'm not very clear, I'm simply not very good with these concepts and I'm genuinely interested in understanding what you're saying.

Update: Ok, I think I understand now.. You're saying that my solution with the spread operator will decrease in performance for each value in the exampleValues array, which is a bad practice. And it's O(n2) (opposed to O(n)) because I'm doing it twice?

O(n2), not O(n2). As in - O(n*n). As the array get bigger, the spread operator takes more and more time to perform because it needs to copy more values, as opposed to push which only needs to add one value (and sometimes increase the size, which takes longer - but it doesn't do it on each push)

O(n2), not O(n2). As in - O(n*n)

I'm aware, I just don't know how to do it on my keyboard. And yes, I do realise there's a major difference and it shouldn't be trivialised..

Anyway, thanks - I learned something new today :)

dev.to does it for you with the ^ operator - so O(n^2) becomes O(n2).

code of conduct - report abuse