These are chat archives for ramda/ramda

11th
Jul 2017
Danni Friedland
@BlueHotDog
Jul 11 2017 01:04
Hey guys, anyone here?
Brad Compton (he/him)
@Bradcomp
Jul 11 2017 01:23
:wave: :bowtie:
Luis Felipe López G.
@luishendrix92
Jul 11 2017 01:47
What is the maximum amount of functions that you've composed?
I'm writing an fp library in C# and my most sane approach is to overload a Compose function with up to 5 functions passed
but what is the average?
James Forbes
@JAForbes
Jul 11 2017 02:34
I usually compose 5-6, but I've definitely exceeded that a number of times and felt comfortable with it, I'd say the max I ever hit was maybe 15 in a single composition. Trying to find examples the largest I've found so far is ~10
Julien Goux
@jgoux
Jul 11 2017 07:33
Hello all ! :D
Julien Bonnin
@JulienBonnin-ABTasty
Jul 11 2017 08:24

Hello everyone. Is there any way I can do this in ramda :

var arr = ['mysubdomain', 'mydomain', 'com'];
const domainFinder = R.findAccum(
  (a) => {
    return a === 'mysubdomain.mydomain.com';
  },
  (a, b) => [a, b].join('.')
);

domainFinder(R.reverse(arr));

What i want is to test in this order :
'com' -> 'mydomain.com' -> 'mysubdomain.mydomain.com'

But I cannot find a method (and findAccum doesn't exist). I have to use mapAccum and a few tricks to get what I want

Jonas Kuiler
@jonaskuiler
Jul 11 2017 09:41
Yo guys, I've read the complete internet and couldn't find how you can reduce an object into an array with Ramda, the only thing I've found is using R.compose(R.map(R.zipObj(['field'])), R.toPairs) (https://github.com/ramda/ramda/wiki/Cookbook#convert-object-to-array)
This is my desired input/output:
const input = {
  "2017-06-07": 2456
}

const output = [{
  price: 2456
  date: "2017-06-07"
}]
Jonas Kuiler
@jonaskuiler
Jul 11 2017 09:49
Additionally what I’m using now is
const toArray = function (object) {
  return R.reduce((acc, prop) => acc.concat(object[prop]), [], R.keys(object))
}
But it feels a bit vague, was wondering if someone knows a “cleaner” solution
Kurt Milam
@kurtmilam
Jul 11 2017 09:52
addIndex, more generally.
Jonas Kuiler
@jonaskuiler
Jul 11 2017 09:54
Okay, I might be to new to this topic… But addIndex/mapObjectIndex both have a fixed input/output type
Kurt Milam
@kurtmilam
Jul 11 2017 09:55
Gah Gitter delete.
mapObjInxeded might be useful in the context of your toArray function (reposting after accidental delete).
Jonas Kuiler
@jonaskuiler
Jul 11 2017 09:58
Ah
True
Kurt Milam
@kurtmilam
Jul 11 2017 09:58
You'd have to use toPairs, I guess. There's been a good deal of discussion ramda/ramda#2046 about whether it makes sense to extend reduce to work directly on objects.
Jonas Kuiler
@jonaskuiler
Jul 11 2017 09:59
Yeah exactly, well I understand the decision there
Read the same thread haha
But the toPairsis probably the best way here
Kurt Milam
@kurtmilam
Jul 11 2017 10:00
Probably, atm.
Jonas Kuiler
@jonaskuiler
Jul 11 2017 10:04
Ok thanks @kurtmilam !
Kurt Milam
@kurtmilam
Jul 11 2017 10:09
:thumbsup:
scarmarco
@scarmarco
Jul 11 2017 14:52
Hello everyone, im new to ramda, I have an obj that starts empty and after api call gets a property, im trying to do a function to access that property (partially applied)
getFirstError = error => {
    return R.ifElse(R.has(error), R.compose(R.prop(error), R.head), R.identity);
  };
console.log(this.getFirstError("mobile")(this.state.errors))
But sadly i get this Unhandled Rejection (TypeError): Cannot read property 'mobile' of undefined
Kurt Milam
@kurtmilam
Jul 11 2017 15:06
@scarmarco what does console.log( this.state.errors ) show?
Michael Rosata
@mrosata
Jul 11 2017 15:06
@scarmarco if getFirstError is on an object (so it's a method). You shouldn't use fat arrow functions as they don't have their own function context (this). Other than that, it seems that this.state.errors doesn't exist. You'd probably want to set a default
R.propOr([], 'errors')(this.state) maybe
scarmarco
@scarmarco
Jul 11 2017 15:08
@kurtmilam its { } and after api call {mobile: [...]}
@mrosata will try that
@mrosata Actually it does exits
check this out
console.log(this.state.errors);
    console.log(this.getFirstError("mobile")(this.state.errors));
image.png
Michael Rosata
@mrosata
Jul 11 2017 15:11
idk, R.when(R.has('mobile'), R.compose(R.prop('mobile'), R.head))({}) doesn't throw an error though when checked in the repl
scarmarco
@scarmarco
Jul 11 2017 15:11
The error shows when the obj actually has the property
thats why im like, wtf?
before, it does run normally
Kurt Milam
@kurtmilam
Jul 11 2017 15:15
I think @mrosata figured it out. Switch to a classic function declaration (no fat arrow) and see what happens.
scarmarco
@scarmarco
Jul 11 2017 15:19
Check on REPL https://goo.gl/3Xd8ah
@mrosata
Michael Rosata
@mrosata
Jul 11 2017 15:20
incCount('mobile')([{ mobile: [1,2,3] }]
wrap the object in an array and it works. because of head. That may have been the issue
@scarmarco so you could use var incCount = error => R.ifElse(R.has(error), R.prop(error), R.identity) instead
scarmarco
@scarmarco
Jul 11 2017 15:21
then how I do access to head of mobile prop?
Michael Rosata
@mrosata
Jul 11 2017 15:21
that refactors to var incCount = error => R.when(R.has(error), R.prop(error))
R.when(R.has(error), o(head, R.prop(error)))
would give you the head
scarmarco
@scarmarco
Jul 11 2017 15:24
what does this mean? o(head, R.prop(error))?
compose?
Michael Rosata
@mrosata
Jul 11 2017 15:24
yea, exactly :)
scarmarco
@scarmarco
Jul 11 2017 15:24
Oh
It worked just changing
Michael Rosata
@mrosata
Jul 11 2017 15:25
If it's possible that mobile would be empty array
// This would check that errors exist and have at least 1 error
R.when(R.propSatisfies(length, error), o(head, R.prop(error)))
scarmarco
@scarmarco
Jul 11 2017 15:25
the position of head and props
holy
Denis Stoyanov
@xgrommx
Jul 11 2017 15:25
@scarmarco getFirstError - just Either
Michael Rosata
@mrosata
Jul 11 2017 15:28
@scarmarco switch around head and prop
scarmarco
@scarmarco
Jul 11 2017 15:28
Yeah, that worked @mrosata
Michael Rosata
@mrosata
Jul 11 2017 15:31
:)
Michael Rosata
@mrosata
Jul 11 2017 16:43
What is the easiest way to create a key renaming function with Ramda to change a single key on an object? I think the below is good, but I could be over-thinking it.
const renameKey = (oldKey, newKey) => converge(
  merge, [
      dissoc(oldKey),
      o(objOf(newKey), prop(oldKey))
    ]
  )
@mrosata also try it compose(invertObj, map(x => x === 'a' ? 'b' : x), invertObj)({a:10})
Michael Rosata
@mrosata
Jul 11 2017 18:09
@xgrommx :thumbsup:
@xgrommx
const renameKey = (oldKey, newKey) => compose(
  invertObj,
  map(when(equals(oldKey), always(newKey))),
  invertObj
)
Brad Compton (he/him)
@Bradcomp
Jul 11 2017 18:17
@ram-bot
const obj = {a: true, b: true, c: false};
const renameKey = (oldKey, newKey) => compose(
  invertObj,
  map(when(equals(oldKey), always(newKey))),
  invertObj
);

renameKey('c', 'd')(obj);
ram-bot
@ram-bot
Jul 11 2017 18:17
{ b: 'true', d: 'false' }
Brad Compton (he/him)
@Bradcomp
Jul 11 2017 18:18
:point_up: gotta be careful with invertObj
Michael Rosata
@mrosata
Jul 11 2017 18:20
@Bradcomp maybe I'll stick with converge(merge, [ dissoc(oldKey), o(objOf( newKey ), prop( oldKey ))] )
Brad Compton (he/him)
@Bradcomp
Jul 11 2017 18:26
I think toPairs and fromPairs is a better isomorphism than invertObj
Denis Stoyanov
@xgrommx
Jul 11 2017 18:28
Michael Rosata
@mrosata
Jul 11 2017 18:29
so
const invertObjPrime = o(fromPairs, toPairs)
const renameKeya = (oldKey, newKey) => compose(
  invertObjPrime,
  map(when(equals(oldKey), always(newKey))),
  invertObjPrime
)
@xgrommx or that too (your repl)
Denis Stoyanov
@xgrommx
Jul 11 2017 18:31
@mrosata lens https://goo.gl/m3GVNv
Denis Stoyanov
@xgrommx
Jul 11 2017 18:37
@mrosata Object.entries({a: true, b: true, c:false}).reduce((a, [k, v]) => Object.assign(a, {[k === 'a' ? 'f' : k]:v}), {}) plain js
Bijoy Thomas
@bijoythomas
Jul 11 2017 18:38
What's a good way to run the same function to each function argument? useWith requires me to replicate the function is the array like useWith(f, [func, func])(arg1, arg2) which starts to get too repetitive with many args .. right now I'm doing something apply(f)(ap([func])([args])
Brad Compton (he/him)
@Bradcomp
Jul 11 2017 18:39
Much lens, very iso, wow: https://goo.gl/QZufQG
Michael Rosata
@mrosata
Jul 11 2017 18:39
@xgrommx nice
at any rate it's a complex problem for one that I can described in 3 words
@bijoythomas what about converge?
maybe unapply first
Denis Stoyanov
@xgrommx
Jul 11 2017 18:41
lift + unnest
unnest(liftN(2, unapply(identity)))(add(10))(10) for example
Bijoy Thomas
@bijoythomas
Jul 11 2017 18:43
@mrosata wouldn't converge pass all args to the func array? I'm looking for something like zip(arr1, arr2) but I want to sort both arr1 and arr2 with the same sort function for example
Denis Stoyanov
@xgrommx
Jul 11 2017 18:43
@bijoythomas provide plain js example
Bijoy Thomas
@bijoythomas
Jul 11 2017 18:47
let mysort = sortBy(identity)

compose(
  apply(zip),
  ap([mysort]),
  unapply(identity)
)(['c', 'b', 'a'], [2,3,1])
just wondering if there is a useWith or perhaps converge variant that allows transforming all args with the same function .. in this case mysort
Denis Stoyanov
@xgrommx
Jul 11 2017 18:51
@bijoythomas useWith(zip, [mysort, mysort])(['c', 'b', 'a'], [2,3,1])
Bijoy Thomas
@bijoythomas
Jul 11 2017 18:52
yes .. but in cases where I have more than 2 args .. the my sort array gets too repetitive .. I could use repeat .. just wondering if there is maybe a better version
Michael Rosata
@mrosata
Jul 11 2017 18:55
@bijoythomas compose(map(mysort), unapply(identity)) assuming mysort is the function you need to repeat
then you still have to do something with the results, but that covers applying each arg to some function
Bijoy Thomas
@bijoythomas
Jul 11 2017 19:00
thanks @mrosata .. I think your code can be used in a shortened version like
compose(
  apply(zip),
  unapply(map(mysort))
)(['c', 'b', 'a', 'd'], [4, 2,3,1])
Michael Rosata
@mrosata
Jul 11 2017 19:00
:)
Denis Stoyanov
@xgrommx
Jul 11 2017 19:01
@bijoythomas oh! I think u mean smth like https://goo.gl/5LmfR6
flatten will be better https://goo.gl/88W55n
Bijoy Thomas
@bijoythomas
Jul 11 2017 19:08
thanks @xgrommx
Heber Nobre
@zbrukas
Jul 11 2017 20:11

Any clues as why

const pokemons = map(assoc('id', uniqueId('pokemon_')))(pkmn)

associates the same id to my objects but

const assignId = (m) => assoc('id', uniqueId('pokemon_'))(m);
const pokemons = map(assignId)(pkmn)

works fine, associating an uniqueId to each?

Tried with fp version of lodash, same output
Kurt Milam
@kurtmilam
Jul 11 2017 20:27
@zbrukas can you put an example on the REPL?
Bijoy Thomas
@bijoythomas
Jul 11 2017 20:27
@zbrukas your first version is similar to
const someid = uniqueId('pokemon_')
const pokemons = map(assoc('id', someid))(pkmn)
the assoc('id', uniqueId('pokemon_')) gets evaluated and assoc('id', someid) gets run on each element
in your second version, assignId is invoked for each element, which results in uniqueId being invoked each time
Kurt Milam
@kurtmilam
Jul 11 2017 20:30
@bijoythomas good eye. I didn't read his problem description carefully enough.
Bijoy Thomas
@bijoythomas
Jul 11 2017 20:30
:thumbsup:
Heber Nobre
@zbrukas
Jul 11 2017 20:32
@bijoythomas Thanks! I thought it would call the function on every map call
Still new to Ramda
How would it be done properly?
Brad Compton (he/him)
@Bradcomp
Jul 11 2017 20:34
The second way you had it looks good to me :smile: