Single man army
A simple recursive program that processes everything in one function. There is a clear mixture of problems that degrades the overall readability of the function. We will see one of these tools for this problem below.
const main = ([x, ...xs], [y, ...ys]) =>
x === undefined || y === undefined
? []
: [ { itemLabel: x.name, itemValue: x.value - y.value } ] .concat (main (xs, ys))
const arr1 =
[ { name: 1, value: 10 }, { name: 2, value: 15 } ]
const arr2 =
[ { name: 3, value: 5 }, { name: 4, value: 3 } ]
console.log (main (arr1, arr2))
Run codeHide result
Thinking with types
This part of the answer is influenced by type theory from the category of monoids - I will not go too far, because I think that the code should be able to demonstrate itself.
, : Foo Bar
Foo
- name
value
Bar
- itemLabel
itemValue
"", , ,
const Foo = (name, value) =>
({ name
, value
})
const Bar = (itemLabel, itemValue) =>
({ itemLabel
, itemValue
})
,
const arr1 =
[ Foo (1, 10), Foo (2, 15) ]
const arr2 =
[ Foo (3, 5), Foo (4, 3) ]
,
console.log (arr1)
console.log (arr2)
. Foo. - , Foo , ( ),
const zip = ([ x, ...xs ], [ y, ...ys ]) =>
x === undefined || y === undefined
? []
: [ [ x, y ] ] .concat (zip (xs, ys))
console.log (zip (arr1, arr2))
: concat
Foo , , . concat
, Foo
const concat = (m1, m2) =>
m1.concat (m2)
const Foo = (name, value) =>
({ name
, value
, concat: ({name:_, value:value2}) =>
Foo (name, value - value2)
})
console.log (concat (Foo (1, 10), Foo (3, 5)))
concat
? Array String Monoid!
concat ([ 1, 2 ], [ 3, 4 ])
concat ('foo', 'bar')
, Foo. name
Foo , value
. "" . , .
const apply = f => xs =>
f (...xs)
zip (arr1, arr2) .map (apply (concat))
, Foo name
value
, , Bar. - - ,
Bar.fromFoo = ({ name, value }) =>
Bar (name, value)
Bar.fromFoo (Foo (1,2))
zip (arr1, arr2)
.map (apply (concat))
.map (Bar.fromFoo)
, . ; .
// main :: ([Foo], [Foo]) -> [Bar]
const main = (xs, ys) =>
zip (xs, ys)
.map (apply (concat))
.map (Bar.fromFoo)
- ,
const Foo = (name, value) =>
({ name
, value
, concat: ({name:_, value:value2}) =>
Foo (name, value - value2)
})
const Bar = (itemLabel, itemValue) =>
({ itemLabel
, itemValue
})
Bar.fromFoo = ({ name, value }) =>
Bar (name, value)
const concat = (m1, m2) =>
m1.concat (m2)
const apply = f => xs =>
f (...xs)
const zip = ([ x, ...xs ], [ y, ...ys ]) =>
x === undefined || y === undefined
? []
: [ [ x, y ] ] .concat (zip (xs, ys))
const main = (xs, ys) =>
zip (xs, ys)
.map (apply (concat))
.map (Bar.fromFoo)
const arr1 =
[ Foo (1, 10), Foo (2, 15) ]
const arr2 =
[ Foo (3, 5), Foo (4, 3) ]
console.log (main (arr1, arr2))
Hide result
.map
- .map
, . [[x1,y1], [x2,y2], ...]
zip
. , , m.map(f).map(g)
m.map(compose(f,g))
. , , , , , -.