1

I'm trying to understand Ramda's transducers. Here's a slightly modified example from the docs:

const numbers = [1, 2, 3, 4];
const isOdd = (x) => x % 2 === 1;
const firstFiveOddTransducer = R.compose(R.filter(isOdd), R.take(5));
R.transduce(firstFiveOddTransducer, R.flip(R.append), [], R.range(0, 100)); //=> [ 1, 3, 5, 7, 9 ]

But what if I want to sum the elements of the resulting array? The following (just adding R.sum into R.compose) doesn't work:

const firstFiveOddTransducer = R.compose(R.filter(isOdd), R.take(5), R.sum);
Eugene Barsky
  • 5,780
  • 3
  • 17
  • 40
  • 2
    If you add `sum`, you're not building a *transducer* but a reduction (a *reducer* with an initial value) – Bergi Aug 30 '20 at 11:59

1 Answers1

4

I'd do something like this, just accumulate on top of an initial 0 value

const list = [1, 2, 3, 4, 5];
const isOdd = R.filter(n => n % 2);

const transducer = R.compose(isOdd);

const result = R.transduce(transducer, R.add, 0, list);

console.log(
  'result',
  result,
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js" integrity="sha512-rZHvUXcc1zWKsxm7rJ8lVQuIr1oOmm7cShlvpV0gWf0RvbcJN6x96al/Rp2L2BI4a4ZkT2/YfVe/8YvB2UHzQw==" crossorigin="anonymous"></script>
Hitmands
  • 13,491
  • 4
  • 34
  • 69
  • Great! I tried to do that but didn't put initial value `0`. – Eugene Barsky Aug 30 '20 at 16:39
  • 1
    Hey, this is an amazing idea! I just wanted to point out, that ramdas `filter` will already return a transducer, so the `compose` call is obsolete. Otherwise, this is absolutely genius. – Luna Oct 24 '22 at 08:34