Last active
June 26, 2019 08:44
-
-
Save 3rdp/7204a7dbb01da2abb77a34499c4e1964 to your computer and use it in GitHub Desktop.
Hitting hobbits for the first time
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** You need to add right body parts */ | |
const asymHobbitBodyParts = [{name: "head", size: 3}, | |
{name: "left-eye", size: 1}, | |
{name: "left-ear", size: 1}, | |
{name: "mouth", size: 1}, | |
{name: "nose", size: 1}, | |
{name: "neck", size: 2}, | |
{name: "left-shoulder", size: 3}, | |
{name: "left-upper-arm", size: 3}, | |
{name: "chest", size: 10}, | |
{name: "back", size: 10}, | |
{name: "left-forearm", size: 3}, | |
{name: "abdomen", size: 6}, | |
{name: "left-kidney", size: 1}, | |
{name: "left-hand", size: 2}, | |
{name: "left-knee", size: 2}, | |
{name: "left-thigh", size: 4}, | |
{name: "left-lower-leg", size: 3}, | |
{name: "left-achilles", size: 1}, | |
{name: "left-foot", size: 2}] | |
/** How would I probably solve this problem in Javascript */ | |
const regexLeft = /^left-/ | |
const rightBodyParts = asymHobbitBodyParts.map(part => { | |
if (regexLeft.test(part.name)) | |
return Object.assign({}, part, | |
{ name: part.name.replace(regexLeft, 'right-') }) | |
}) | |
const symmetric = asymHobbitBodyParts.concat(rightBodyParts.filter(Boolean)) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; Brave Clojure takes a slightly different approach | |
;; This code doesn't check for a 'left-' in a name | |
;; Instead, and this is pure genius, it removes a duplicate object, like when name is nose, by using set sctructure | |
(defn matching-part | |
[part] | |
{:name (clojure.string/replace (:name part) #"^left-" "right-") | |
:size (:size part)}) | |
(defn symmetrize-body-parts | |
"Expects a seq of maps that have a :name and :size" | |
[asym-body-parts] | |
(loop [remaining-asym-parts asym-body-parts | |
final-body-parts []] | |
(if (empty? remaining-asym-parts) | |
final-body-parts | |
(let [[part & remaining] remaining-asym-parts] | |
(recur remaining | |
(into final-body-parts | |
(set [part (matching-part part)]))))))) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** You need to add right body parts */ | |
const asymHobbitBodyParts = [{name: "head", size: 3}, | |
{name: "left-eye", size: 1}, | |
{name: "left-ear", size: 1}, | |
{name: "mouth", size: 1}, | |
{name: "nose", size: 1}, | |
{name: "neck", size: 2}, | |
{name: "left-shoulder", size: 3}, | |
{name: "left-upper-arm", size: 3}, | |
{name: "chest", size: 10}, | |
{name: "back", size: 10}, | |
{name: "left-forearm", size: 3}, | |
{name: "abdomen", size: 6}, | |
{name: "left-kidney", size: 1}, | |
{name: "left-hand", size: 2}, | |
{name: "left-knee", size: 2}, | |
{name: "left-thigh", size: 4}, | |
{name: "left-lower-leg", size: 3}, | |
{name: "left-achilles", size: 1}, | |
{name: "left-foot", size: 2}] | |
/** How would I probably solve this problem in ~Javascript~ ES6 */ | |
const regexLeft = /^left-/ | |
const matchingPart = part => { | |
const newName = part.name.replace(regexLeft, 'right-') | |
if (newName !== part.name) return { ...part, ...{ name: newName }} | |
} | |
const symmetrize = asymBodyParts => { | |
const finalBodyParts = new Set() | |
asymBodyParts.forEach(part => { | |
finalBodyParts.add(part) | |
finalBodyParts.add(matchingPart(part)) | |
}) | |
finalBodyParts.delete(undefined) // clean up | |
return finalBodyParts; | |
} | |
symmetrize(asymHobbitBodyParts) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** You need to add right body parts */ | |
const asymHobbitBodyParts = [{name: "head", size: 3}, | |
{name: "left-eye", size: 1}, | |
{name: "left-ear", size: 1}, | |
{name: "mouth", size: 1}, | |
{name: "nose", size: 1}, | |
{name: "neck", size: 2}, | |
{name: "left-shoulder", size: 3}, | |
{name: "left-upper-arm", size: 3}, | |
{name: "chest", size: 10}, | |
{name: "back", size: 10}, | |
{name: "left-forearm", size: 3}, | |
{name: "abdomen", size: 6}, | |
{name: "left-kidney", size: 1}, | |
{name: "left-hand", size: 2}, | |
{name: "left-knee", size: 2}, | |
{name: "left-thigh", size: 4}, | |
{name: "left-lower-leg", size: 3}, | |
{name: "left-achilles", size: 1}, | |
{name: "left-foot", size: 2}] | |
/** How would I probably solve this problem in ES7 & functional programming */ | |
// fp helpers | |
const compose3 = (f, g, v) => x => f(g(v(x))) | |
const curry = (fn) => { | |
const arity = fn.length; | |
return function $curry() { | |
var args = Array.from(arguments) | |
if (args.length < arity) { | |
return $curry.bind.apply($curry, [null].concat(args)) | |
} | |
return fn.apply(null, args) | |
} | |
} | |
const id = x => x | |
const newSet = array => { | |
return new Set(array) | |
} | |
// program | |
const replace = curry((what, withWhat, x) => x.replace(what, withWhat)) | |
const regexLeft = /^left-/ | |
function getMatchingPartName(partName) { | |
return replace(regexLeft, 'right-', partName) | |
} | |
const matchingPart = part => { | |
const newName = getMatchingPartName(part.name) | |
if (newName !== part.name) return { ...part, ...{ name: newName }} | |
else return part // same reference, Set will filter this out | |
} | |
function sortNonUnique(parts) { | |
return compose3(Array.from, newSet, id)(parts) | |
} | |
const symmetrize = asymBodyParts => { | |
let finalBodyParts = [] | |
asymBodyParts.forEach(part => { | |
finalBodyParts = [...finalBodyParts, ...sortNonUnique([part, matchingPart(part)])] | |
}) | |
return finalBodyParts; | |
} | |
symmetrize(asymHobbitBodyParts) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
OK, but now there's three times more code. And three times less JS programmers can read it. :(
Next Action:
Try partical application instead of currying. Create function
replaceLeftWithRight
. Rm usage of id insortNonUnique
.