These are chat archives for ramda/ramda

24th
Mar 2019
Simon Bailey
@thebailers
Mar 24 15:38
Hey all, how can I do the same as the first line, using Ramda? 2nd line is an attampt, but completely wrong :(
const body = csvBodyArray.map(c => c.filter((el, i) => targetColumnIndexes.indexOf(i) != -1))
const body2 = compose(map(filter(gte(0)), targetColumnIndexes))(csvBodyArray)
Rakesh Pai
@rakeshpai
Mar 24 16:45
@thebailers Haven't tried this, but it should work:
const body = map(filter(flip(includes)(targetColumnIndexes)))(csvBodyArray)
Simon Bailey
@thebailers
Mar 24 16:58
Thanks @rakeshpai - what is flip for?
Hmm no it just returns empty arrays
Jonah
@jonahx
Mar 24 16:59
@thebailers flip will reverse the order of arguments of a function.
Simon Bailey
@thebailers
Mar 24 17:01
Struggling here
This is what the data is:
// targetColumnIndexes = [0,1]
// csvBodyArray = [ 'LKR', 'Sri Lanka Rupee', 'LK' ]
Jonah
@jonahx
Mar 24 17:01
@thebailers which part?
Simon Bailey
@thebailers
Mar 24 17:01
csvBodyArray is multiple arrays of currencies
targetColumn indexes are the indexes I want to return for each currency, so first and second element in the array
Started here:
const indexExists = n => contains(n, targetColumnIndexes)
    const body2 = compose(map)(csvBodyArray)
Jonah
@jonahx
Mar 24 17:02
@thebailers 1s
Simon Bailey
@thebailers
Mar 24 17:02
Thought I could map over the csvBodyArray, and for each, filter using the indexExists fn
But struggling with the syntax
Ben Briggs
@ben-eb
Mar 24 17:08
What is the expected output for this function?
Because your example function does not work:
const targetColumnIndexes = [0,1]
const csvBodyArray = [ 'LKR', 'Sri Lanka Rupee', 'LK' ]

csvBodyArray.map(c => c.filter((el, i) => targetColumnIndexes.indexOf(i) != -1)) // c.filter is not a function
Simon Bailey
@thebailers
Mar 24 17:28

@ben-eb it’s:

[ 'LKR', 'Sri Lanka Rupee' ],

It works with this:

const body = csvBodyArray.map(c => c.filter((el, i) => targetColumnIndexes.indexOf(i) != -1))

But want to do the same using ramda
Ben Briggs
@ben-eb
Mar 24 17:29
So you have an array of arrays?
Simon Bailey
@thebailers
Mar 24 17:29
exactly
Ben Briggs
@ben-eb
Mar 24 17:29
Do the indexes need to change?
Jonah
@jonahx
Mar 24 17:29
@thebailers this does it
const fn = (idxs, data) => map(ap(map(nth, idxs)), map(of, data))
Simon Bailey
@thebailers
Mar 24 17:29
And for each, I want to only returned the elements found at the index passed from targetColumnIndexes
could probably simplify further but that does it in 1 line, so...
Simon Bailey
@thebailers
Mar 24 17:30
thanks @jonahx give me five mins and I will plug it in, give it a go
Ben Briggs
@ben-eb
Mar 24 17:30
If the indexes are just first two every time, map(take(2)) works
Simon Bailey
@thebailers
Mar 24 17:30
kids are fighting :)
@ben-eb it will be different indexes for different csv files
Ben Briggs
@ben-eb
Mar 24 17:31
Ahh right, @jonahx's solution should do the trick in this case :)
Simon Bailey
@thebailers
Mar 24 17:32
thank you guys, really appreciate it
Jonah
@jonahx
Mar 24 17:32
Np :)
Simon Bailey
@thebailers
Mar 24 17:36
@jonahx how am I calling fn on cvsBodyArray?
Jonah
@jonahx
Mar 24 17:37
@thebailers check out the link i posted above:
fn(indexes, csvBodyArray)
Simon Bailey
@thebailers
Mar 24 17:38
Woof!
there it is
Thanks man :)
@jonahx any chance you could briefly explain what it does?
Jonah
@jonahx
Mar 24 17:40
Sure. gimme a few
Simon Bailey
@thebailers
Mar 24 17:50
Think I get it, map(of, data) passes each element in turn to map(nth, indexes) which returns the array eklement from data at the indexed numbers?
Not sure what ap does
Jonah
@jonahx
Mar 24 17:54

yeah that’s the only tricky part. so map(nth, idxs) creates an array of functions, one for “picking out” each of your indexes. ap, per the docs, "applies a list of functions to a list of values”. in our case, the “list of values” is not the rows themselves, but each individual row. hence we have to of each row to make it a list, and we have to map the ap.

i feel like this would be easier if i had a white board and could draw pictures, but if you cross reference what i just said with the docs on ap and play around with some other examples of ap, it should make sense after not too long

Simon Bailey
@thebailers
Mar 24 17:56
i really appreciate that man, thanks so much
Jonah
@jonahx
Mar 24 17:56
anytime
Simon Bailey
@thebailers
Mar 24 17:56
It’s taking a while for all this to click, just got to play around as you say, keep using it
out of interest, isn’t filter a simpler option? To reason about?
Map over the data, and filter by the index, checking it against the array of indexes to keep
Jonah
@jonahx
Mar 24 18:07
@thebailers ofc “simpler” is relative to “what primitives have already become muscle memory”. ap is a good one to add to that list. but to answer your question, mapping a filter is a fine way to approach it as well. the only downside is it forces you to think about low-level details a bit more, conceptually. generally speaking solutions that avoid i are cleaner and higher-level imo. again, there’s no “right” answer. your set of comfortable primitives determines what your taste will be.
Simon Bailey
@thebailers
Mar 24 18:10
yeah makes sense
jut got to try to make this click

map(nth, idxs) creates an array of functions, one for “picking out” each of your indexes

I really don’t understand this

what are the functions within the array
Ben Briggs
@ben-eb
Mar 24 18:12
It works because nth takes two arguments
So the first pass will partially apply nth
Jonah
@jonahx
Mar 24 18:13
exactly
so you are left with an array of “functions for picking out indexes"
Ben Briggs
@ben-eb
Mar 24 18:13
Yep :)
Simon Bailey
@thebailers
Mar 24 18:13
So first time round, nth takes the indexes?
Is it taking them one at a time, in a map? So 0, then 1 separately?
Ben Briggs
@ben-eb
Mar 24 18:14
Yep
Jonah
@jonahx
Mar 24 18:14
Yeah, you are left with [fn_that_gets_0, fn_that_gets_1]
Simon Bailey
@thebailers
Mar 24 18:14
I seeee!
Ben Briggs
@ben-eb
Mar 24 18:15
Once you get this intuition it opens up so many possibilities
Simon Bailey
@thebailers
Mar 24 18:15
I am a bit old for this, it takes my brain so long, haha
Jonah
@jonahx
Mar 24 18:15
then if ap that to, say [[‘a’, ‘b’, ‘c’]], you’d get [‘a’, ‘b’]
from there, you should be able to say why need to map the ap and do the map(of, data) part
Simon Bailey
@thebailers
Mar 24 18:17
Ok… going back over the explanations
Right, so we have an array of functions of nth with the indexes, 0 and 1, then we map over each line in the data… we need to map the ap, so we can run pass each item within each row to the nth function to determine whether we keep it or not?
If that’s right (lol) it’s kind of clear, but it’s still a leap of faith, I am very muddy on how it all works
Jonah
@jonahx
Mar 24 18:24

not quite (i think)

So, again from docs:

ap applies a list of functions to a list of values.

The “list of functions” in our case is [fn_that_gets_0, fn_that_gets_1]. i think you’re clear on that. the tricky part is the 2nd part.

the “list of values” is a list with one element, like: [[‘a’, ‘b’, ‘c’]]. each function gets applied to each “element of that list”. ie, each function get applied to [‘a’, ‘b’, ‘c’]. then the results of those applications are concatenated together.

so fn_that_gets_0 returns a, and fn_that_gets_1 returns b, and the final results is [‘a’, ‘b’], as intended

Simon Bailey
@thebailers
Mar 24 18:26
ahh i see
that makes sense