These are chat archives for ramda/ramda

25th
Jul 2018 Kurt Milam
@kurtmilam
Jul 25 2018 16:13
I am super stumped on a problem that involves reducing an array of arrays: https://goo.gl/HynyYQ
Hoping someone can help me with the magic part :D
``````const maxValue = 9

const grandTotal = o(rowTotal, map(rowTotal))

// need some magic here that lets me double each array element
// as long as the sum of all array elements <= maxValue
const doubleRow = reduce(
(acc, x) => append(multiply(2, x), acc),
[]
)
const doubleAllRows = reduce(
(acc, x) => append(doubleRow(x), acc),
[]
)

const input = [
[1, 1],
[1, 1, 1],

]
console.log(grandTotal(input)) // 6

const desiredOutput = [
[2, 2],
[2, 1, 1],

]
console.log(grandTotal(desiredOutput)) // 9 (i.e. maxValue)

const actualOutput = doubleAllRows(input)
/*
[
[2, 2],
[2, 2, 2],

]
*/

console.log(grandTotal(actualOutput)) // 12`````` perkee
@perkee
Jul 25 2018 17:11
okay this looks like it might be a job for `mapAccum`
we need to map over every value in the structure and we need to keep track of an accumulated total, so that's what springs to mind Kurt Milam
@kurtmilam
Jul 25 2018 17:13
that sounds promising - I will take a look. Mike Lambert
@lax4mike
Jul 25 2018 17:14
can you just use `R.when`?
``````const doubleRow = R.when(
(arr) => R.sum(arr) < 10,
R.reduce(
(acc, x) => R.append(R.multiply(2, x), acc),
[]
)
);`````` Kurt Milam
@kurtmilam
Jul 25 2018 17:21
@lax4mike I don't think that will do the trick, since `doubleRow` isn't aware of the `grandTotal`. perkee
@perkee
Jul 25 2018 17:23
so here's a dumb example that ignores the nested nature of it but gets the ball rolling: https://codepen.io/perkee/pen/yqXmEo

inline:

``````const { sum, ifElse, mapAccum } = R;
const maximum = 40;
const fn = (acc, value) => {
const double = 2 * value;
const doubleAcc = double + acc;
if (doubleAcc < maximum) {
return [ doubleAcc, double ]
}
return [ value + acc, value ];
}

const arr = [ 3, 8, 3, 1, 2, 3, 1, 1 , 1 ];
console.log(JSON.stringify(mapAccum(fn, 0, arr)))
// result is [41,[6,16,6,2,4,3,2,1,1]], so first element is running total, second is this row transformed``````

The real trick is how to pass the running total into the mapAccum on the next row

I leave it to you to turn `fn` into something rad and pointfree Kurt Milam
@kurtmilam
Jul 25 2018 17:27
This seems to do the trick but is a bit of a mind-bender: https://goo.gl/7tyUvs Mike Lambert
@lax4mike
Jul 25 2018 17:27
hmm, how would that work in the situation that doubling a row will make the grand total over, but not doubling that row will make the grand total under? Kurt Milam
@kurtmilam
Jul 25 2018 17:27
`<=` is fine.
I have a max value. Any result that is less than or equal to that max value is acceptable. Mike Lambert
@lax4mike
Jul 25 2018 17:28
after you double them (or not) perkee
@perkee
Jul 25 2018 17:28
you stop doubling on the element in the row where it puts the total over, not on the row where doubling would put you over
at least that's what I got from the example :shrug: Kurt Milam
@kurtmilam
Jul 25 2018 17:29
See the (apparently working) example I linked above. (linking again here https://goo.gl/QZ9HT8 ).
@perkee that's correct.
Works for all max values from 6 (the input's grand total) through 12 (the grand total if all array elements are doubled), so it appears to do the trick.
@perkee thanks for mentioning `mapAccum` and for your example! perkee
@perkee
Jul 25 2018 17:45
np! and good luck friend!