Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Jan 31 2019 22:17
    CrossEye commented #2779
  • Jan 31 2019 21:04
    ArturAralin commented #2779
  • Jan 31 2019 20:08
    CrossEye commented #2779
  • Jan 31 2019 18:56
    buzzdecafe commented #2631
  • Jan 31 2019 18:09
    ArturAralin commented #2779
  • Jan 31 2019 16:18
    CrossEye commented #2779
  • Jan 31 2019 16:10
    CrossEye commented #2631
  • Jan 31 2019 16:06
    CrossEye commented #2777
  • Jan 31 2019 14:44
    ArturAralin opened #2779
  • Jan 31 2019 07:39
    inferusvv commented #2631
  • Jan 31 2019 03:07
    sespinozj commented #2771
  • Jan 31 2019 02:33
    machad0 commented #2771
  • Jan 31 2019 02:26
    JeffreyChan commented #2777
  • Jan 30 2019 14:30
    CrossEye closed #2777
  • Jan 30 2019 12:13
    vanyadymousky updated the wiki
  • Jan 30 2019 01:42
    JeffreyChan commented #2777
  • Jan 29 2019 21:06
    vanyadymousky updated the wiki
  • Jan 29 2019 16:28
    CrossEye commented #2777
  • Jan 29 2019 15:50
    mbostock commented #2772
  • Jan 29 2019 15:48
    CrossEye commented #2772
Martin Algesten
@algesten
@davidchambers @CrossEye @jethrolarson thanks!!! i'm about to put it into production code at work today. so i'll have it a bit more road tested.
@jethrolarson i have considered that. the order is to do with fnuc. but i want to play nice with the community. so i have a thought that require('zu/inverse') would give me same API but reverse order. i would consider making the default order expr/nodes since i acknowledge i may be the odd one out with fnuc.
Jethro Larson
@jethrolarson
Not heard of fnuc. I'll check it out
Jethro Larson
@jethrolarson
Is it a weird irony that it's "func" but jumbled :smile: neat stiff though
Raine Virta
@raine
@CrossEye I wonder if the @typedef annotation is used correctly. http://usejsdoc.org/tags-typedef.html
Scott Sauyet
@CrossEye
@raine: it's pretty clearly not used in the way JSDoc would like.
Martin Algesten
@algesten
@jethrolarson fnuc was me throwing toys out of the pram with ramda argument order. since then however, ramda has gone deep into fantasyland territory and i’m lost. i still use my own lib, but i know i must raise my game and understand why i would want functors, monads, etc.
Alex Schenkman
@alesch

Hi ramda folks,
I’m new to rambda and I would like to transform this JSON:

{
   ‘2’ : { ‘name': ‘two’},
  ‘1’ : {’name’ : ‘one’}
}

into some sorted iterable (list?) like this:

 [ 
{ id: ‘1’, name: ‘one'},
{ id: ‘2’, name: ’two'}
]

In other words I need to:

  1. Iterate throgh the object entries, and set the id property to its key.
  2. Iterate on that and sort by id.

How can I do this in an elegant way? All my attempts become quite imperative.
Thanks!

Danielle McLean
@00dani
@alesch Here's one way.
R.pipe(
  R.mapObjIndexed( R.flip( R.assoc('id') )),
  R.values,
  R.sortBy(R.prop('id'))
)
Alex Schenkman
@alesch
@00Davo Thank you, I’ll read up on those functions.
Scott Sauyet
@CrossEye
Another: R.converge(R.zipWith(R.assoc('id')), R.keys, R.values). Note that if your ids are actually integers you won't need an additional sort.
Danielle McLean
@00dani
Oh. Whoops, my version compares the IDs as strings and so won't work if there're multiple digits. :blush: This fixes it, but @CrossEye's version is also correct and shorter so. Yeah.
R.pipe(
  R.mapObjIndexed( R.useWith(R.flip(R.assoc('id')), R.identity, Number)),
  R.values,
  R.sortBy(R.prop('id'))
)
Martin Algesten
@algesten
every time i reach for R.pipe i feel a bit disappointed with myself...
Alex Schenkman
@alesch
Thank you @CrossEye. I’ll have to digest that one, :-P
Scott Sauyet
@CrossEye
@algesten: what's wrong with pipe?
Stefano Vozza
@svozza
real men use compose :stuck_out_tongue:
Martin Algesten
@algesten
@CrossEye i use it when i struggle to think functions; when i rather think sequence of operations. it's borderline imperative programming.
your above "converge" was one of those omg-moments for me. it solves a thing i do a R.pipe for every time.
Alex Schenkman
@alesch

@CrossEye Would you help me understand your suggestion, please?

f = R.assoc('id')
g = R.zipWith( f );
R.converge(g, R.keys, R.values);

I understand that we are partially applying arguments.
assoc takes 3 arguments. The last one is the list itself.
But what happens with the second one?

Martin Algesten
@algesten
@alesch R.assoc('id') expects two more arguments 1. the value for id and 2. an object to shallow copy and put {id:arg1} into.
R.zipWith with a function that accepts two arguments (1. and 2. above) will then be expecting one array of 1. and one array of 2.
R.keys gives you the array of 1.s and R.values an array of 2.s
Scott Sauyet
@CrossEye
I guess I'm just a quiche-eater. I love pipe! I feel a little dirty when I have to resort to converge or useWith. I'm glad we have them, but I prefer nice pipelines of functions.
Martin Algesten
@algesten
hm. ok. if you say so. perhaps i try compose, to see whether backwards feels better ;)
Scott Sauyet
@CrossEye
Thank you @algesten. I struggle to explain these things succinctly.
Martin Algesten
@algesten
not sure i managed to. but i wanted to take a stab.
Aldwin Vlasblom
@Avaq

@alesch I also found CrossEyes answer pretty astounding, so I picked it apart in the REPL. Let's start with converge:

//converge(f, a, b)(x) === f(a(x), b(x))
//so:
R.converge(R.zipWith(R.assoc('id')), R.keys, R.values)(x) //===
R.zipWith(R.assoc('id'))(R.keys(x), R.values(x)) //===
R.zipWith(R.assoc('id'), R.keys(x), R.values(x))

Now R.keys and R.values both produce lists. One containing the ID's (keys) and the other containing objects (values). And as it happens, R.zipWith(f) wants two lists, and it'll pass a pair of items (taken from both lists) into f so that f may produce a single item for the returned list.

In this case we use R.assoc('id') as our f (zipper function), which will receive the ID from the first list, and the object from the second and return a new object on which the "id" property will have been set.

Scott Sauyet
@CrossEye
An important point here is the parallel between keys and values. They are ordered in parallel. The fourth entry in the list of values is the value of the property of the object at the fourth entry in the list of keys. Without that, this would not work.
Scott Sauyet
@CrossEye
A version of the same technique where that association is not so important would be R.compose(R.map(R.apply(R.assoc('id'))), R.toPairs). The tradeoff is having to call R.apply. But this might be a little cleaner.
Martin Algesten
@algesten
well done avoiding R.pipe there ;)
Scott Sauyet
@CrossEye
Just for you. I wrote it as pipe because that's how I think, and reversed it to compose :smile:
Martin Algesten
@algesten
haha! :D
just out of curiosity. does Object.keys guarantee an order?
or that multiple invocations will have the same order as a result.
Scott Sauyet
@CrossEye
Very big point of contention now. #1067.
Scott Sauyet
@CrossEye
It is not really consisyent with our notion of equals. Two things we think of as equal could have different order of keys. I'm proposing a change, but there's significant opposition.
Martin Algesten
@algesten
I'm reading. just now at the bit where jdalton appear to be wilfully obtuse regarding the natural order of a list.
Scott Sauyet
@CrossEye
He's not just trolling, even if it sometimes feels that way. He does have serious points to make. And decisions here are clearly not as obvious to everyone as I would have thought. Lots of smart people with lots of different opinions.
John-David Dalton
@jdalton
:hear_no_evil:
Martin Algesten
@algesten
:blush:
Scott Sauyet
@CrossEye
... and jdalton is one of them :angel:
Raine Virta
@raine

I think the arrow syntax is a bit too loose

let foo = (a) => ... // ok
let bar = () => ... // ok
let baz = a => ... // ok
let xyz = => ... // not ok

however in case of map(x => x*x) I can understand without parens it's more readable

John-David Dalton
@jdalton
Arrow funcs are nice
I donno why skinny arrow wasn't done (no lexical bind)
like CS. There was prolly a ton of discussion (as per usual)
Alex Schenkman
@alesch
@algesten @Avaq @CrossEye Thank you all for the explanations. I’ll have to study them more.
@CrossEye You said you used compose but you thought of it with pipe. How would it be with pipe? In case it becomes easier to read for me.
Scott Sauyet
@CrossEye
R.pipe(R.toPairs, R.map(R.apply(R.assoc('id')))) -- just reversing the parameter order.
Aldwin Vlasblom
@Avaq

@alesch pipe is just compose but reversed: pipe(a, b, c) === compose(c, b, a)

I think compose is meant to resemble nested-function calling, like so: compose(a, b, c)(x) looks like a(b(c(x)))

And pipe is meant to resemble piping, like so: pipe(a, b, c)(x) looks like x > a | b | c

Or that's how I think of them anyway. ;)