Skip to content

Instantly share code, notes, and snippets.

@Ntropish
Created October 1, 2019 04:07
Show Gist options
  • Save Ntropish/0da8049d2aea6aa44df3ef9405331fed to your computer and use it in GitHub Desktop.
Save Ntropish/0da8049d2aea6aa44df3ef9405331fed to your computer and use it in GitHub Desktop.
//=============================================================================
// Original
//=============================================================================
var scrKeys = Object.keys(source)
return collection.filter(obj => srcKeys.map(key => obj[key] === souce[key])
.map(key => obj[key] === souce[key]).
reduce((a, b) => a && b
)
)
//=============================================================================
// Formatted via https://prettier.io/playground/
//=============================================================================
var scrKeys = Object.keys(source);
return collection.filter(obj =>
srcKeys.map(key => obj[key] === souce[key]).reduce((a, b) => a && b)
);
//=============================================================================
// Extract functions
//=============================================================================
var scrKeys = Object.keys(source);
var srcKeyEqualOnBoth = key => obj[key] === souce[key];
var andAll = (a, b) => a && b;
var keysMatchSource = obj => srcKeys.map(srcKeyEqualOnBoth).reduce(andAll);
return collection.filter(keysMatchSource);
@Ntropish
Copy link
Author

Ntropish commented Oct 1, 2019

Here's an explanation of what keysMatchSouce does as it goes through its two function calls

  1. The keys that need to match are all tested against the object: [ sourceKeys[0], sourceKeys[1] ]

  2. These are the intermediate values after testing. Key 0 existed on the object but 1 did not: [ true, false ]

  3. The reduce results in false because every value didn't match. It only returns true if every value is true

Reduce is hard to understand if you don't have a feel for what it does so I'm just going to give some examples.

Single Value Array

Input [true]

Output true

The first value is extracted and returned

Two Valued Array

Input
[true, true]

output
true

The output was determined by calling addAll(true, true) = true && true = true

Three Valued Array

Input
[true, true, false]

output
false

The output was determined by calling addAll(addAll(true, true), false) = true && true && false = false

Calling with 4 or more items will just make more calls nested similarly.

andAll

First off, I should have just called this and because that's all it does.

var andAll = (a, b) => a && b;

But this is a reducer function. Reducer functions answer the question:

Given the current accumulator value and some item on this list -- what is the next accumulator value?

This isn't a very complicated question but you can make almost any list operation by answering it. In this case andAll expressed in English is saying:

If the value up to this point is true and this next item is also true then the value will stay true. If either is false then the value will be false.

By answering this question they were able to create behavior that ANDs every item together.

This is just one case you'll come across, there's a ton of different ways to use reduce. But just keep in mind that boolean operations are associative and effectively join together in a reducer. That will get you through any other cases like this.

@Ntropish
Copy link
Author

Ntropish commented Oct 1, 2019

Also, with the transformations, it might seem hard to justify extracting all of those functions. But think of it as "relaxing" the code. The prettier version is compact and nice looking, but it's sort of "constricted" in that everything is stuck together on one line and it can't be modified easily. This is really important when working on real projects that change constantly. But it's also the technique I use when I feel like something is too difficult. Just start relaxing the code, breaking things up, and naming them so you can start thinking about them in English.

These extracted functions/data eventually merge into reusable utilites.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment