tap((x) => console.log(x))
after a filter statement in a pipeline? [ts] No overload matches this call.
The last overload gave the following error.
Argument of type 'FilterOnceApplied<unknown>' is not assignable to parameter of type '(x: unknown) => unknown[]'.
Type 'unknown[] | Dictionary<unknown>' is not assignable to type 'unknown[]'.
Type 'Dictionary<unknown>' is missing the following properties from type 'unknown[]': length, pop, push, concat, and 26 more.
const data = [
{ title: "One", date: "2021-03-03" },
{ title: "Two", date: "2020-03-03" },
{ title: "Three", date: "2021-03-22" },
{ title: "Four", date: "2020-03-03" },
{ title: "Five", date: "2020-02-23" },
]
@hybrid_alex_twitter , try the following:
const addMonth = request => {
const date = new Date(request.date)
const month = date.toLocaleString("default", { month: "long" })
return {
...request,
month
}
}
const byMonth = R.groupBy(R.prop('month'))
const withMonth = data
.map(addMonth)
byMonth(withMonth)
the output should be:
{
"February":[
{
"date":"2020-02-23",
"month":"February",
"title":"Five"
}
],
"March":[
{
"date":"2021-03-03",
"month":"March",
"title":"One"
},
{
"date":"2020-03-03",
"month":"March",
"title":"Two"
},
{
"date":"2021-03-22",
"month":"March",
"title":"Three"
},
{
"date":"2020-03-03",
"month":"March",
"title":"Four"
}
]
}
map
will work on Objects, so you'll end up with something like:{
1999: {
January: [...],
...
},
2000: {
January: [...],
...
},
...
}
converge()
function: https://ramdajs.com/docs/#converge, but it's a little hard to work out what's going on at first. You might like to read through https://jrsinclair.com/articles/2019/compose-js-functions-multiple-parameters/, which explains how this works. Essentially the converge()
function generalises lift
for functions to work with any number of parameters.
[{}...{v:1}..{}]
, and I'd like to modify some of them and return the others untouched, like '[{}...{v:2}...{}]`. Basically, it's like clone the original array then do a for-each loop. But I want to do it in a functional way. Does R provide some function to do this?
const someFunction = (param1, param2, array) => implementation
const someOtherFunction = (array) => implementation
const someFunctionCurried = R.curry(someFunction)
const func = someFunctionCurried('foo', 'bar') //curried function with the two params without the array
const pipeFunction = R.pipe(someFunction, someOtherFunction)
return pipeFunction(data) //passing the array
is unionWith function right?
The order of the params for the predicate function looks wrong to me. First parameter corresponds with the second object. and second parameter corresponds with the first object. This makes the first example to fail and the second to work.
R.unionWith((l, r) => l.date.substr(0,10) === r.date, [{date:'2020-01-02T00:00:00'}], [{date:'2020-01-02'}])
//? [{date:'2020-01-02T00:00:00'}, {date:'2020-01-02'}]
And this works:
R.unionWith((l, r) => l.date === r.date.substr(0,10), [{date:'2020-01-02T00:00:00'}], [{date:'2020-01-02'}])
//? [{date:'2020-01-02T00:00:00'}]
this is a more theoretical question since I'm a FP newbie. I want to understand functors and monads so I know how they work and understand how to use them in my application. Today, while reading Joy of Javascripts (I'm a static language OOD for most of my career) I noticed the following code:
const unique = letters => Array.from(new Set([...letters]))
class Id {
#val
constructor(value) {
this.val = value
}
static of(value) {
return new Id(value)
}
get() {
return this.val
}
}
Id.of('aabbcc').get()
'aabbcc'
//this is where I get lost
const Functor = {
map(f = identity) {
return this.constructor.of(f(this.get()))
}
}
Object.assign(Id.prototype, Functor);
Id.of('aabbcc').map(unique).get()
[ 'a', 'b', 'c' ]
In here Id
, is pretty straightforward. I also see (more or less) how they added the functionality of map
by adding the Functor
but I get lost on the
return this.constructor.of(f(this.get()))
it seems that you are accessing the container (in this case will be the instance of class (object) Id
) and get the value passed. Later, it seems that to actually add the functionality by adding the the mixing Functor
to the Id
.
I often compose a series of lenses to update various pieces of an object. Sometimes, I find that I need a value from another part of that object, that was just updated in this pipeline, in order to correctly derive another property.
Is there a utility that would help here? I usually just use an arrow function, and reference the values as needed. But am curious if there's a better way.
R.compose(
st => R.over(R.lensProp("data"),
R.map(
R.set(
R.lensProp("selected"),
st.isSelectAll,
),
),
),
R.over(R.lensProp("isSelectAll"), R.not),
)(state);
pluck
a particular event, say correlationId
from multiple objects and arrays? I am creating an error handler and I want to log the correlationId and send it to my error handler. But there are some objects where the correlationId
is nested in different places. Sometimes the events are arrays as well.
Hey guys!
Wanted to say again how good ramda is, integrated it on my job and aiming FP path there to reliably handle data processing. Having good feedback from colleagues as well! <3
There is question lately though, that might look trivial, but I have feeling there is solution from FP world that I am just missing.
We use Ramda together with Redux. Particularly, it's useful to compose selector functions as computations (functions that have state -> a
signature).
Let's say we have 2 selector functions, one of which needs to use data from another. One selector gets number, other array and I want to use that number as index to array. It looks like this now, using R.nth:
// string[] -> AppState -> string
const nthOfList = list => R.pipe(
R.path(["myData", "myIndex"]),
R.nth,
list
);
// AppState -> string[]
const list = R.pipe(
R.path(["myOtherData", "myArray"])
);
Now I want to apply list
to the nthOfList
, but need to call functions with state to get actual list and actual result, because all of them expect state to run
computation:
// f(g(x), x)
const elementByIndex = nthOfList(list(state))(state);
But it becomes cumbersome to read quite quickly. I recognized that this is signature of chain
and it worked:
const elementByIndex = R.chain(nthOfList, list);
elementByIndex(state);
I'm 99% certain this is some pattern that means something. Is this use case of State monad? I imagine something like this. I would appreciate if you could point me to it. Maybe there is easier way to do what I'm doing (of course I can just write R.nth(myIndexSelector(state), myArray(state))
for this case, but we have many other cases).
The general pattern is "compose 2 selectors without passing state for each of them separately, but passing it once". I have feeling I discovered something from FP wolrd but I'm not sure what :)
@tofo_gitlab: I think it's reasonable to call ramda 'production ready'; I and many others have been using it in shipped code for years.
Personally, using ramda isn't a decision I'd feel the need to share with a client. I use ramda for internals, not exposed as my api or anything, so it'd be a bit like telling a client i was using 'let' instead of 'const'.
What are you looking to see in a v1?
R.merge will merge objects by array index. But given:
[
{"key": 1, "a": "a", bar: "baz"},
{"key": 2, "b": "b", bar: "bar"}
]
and
[
{"key": 1, "a": "x", baz: "baz"},
{"key": 3, "b": "x", baz: "baz"}
]
the result should be:
[
{"key": 1, "a": "x", bar: "bar", baz: "baz"},
{"key": 2, "b": "b", "bar": "bar"},
{"key": 3, "b": "x", "baz": "baz"}
]
So .. the only object that was merged was the one containing { key: 1 }...