input
to output
:const input = [
{ id: 1, name: 'a', parentId: null },
{ id: 2, name: 'b', parentId: 1 },
{ id: 3, name: 'c', parentId: 4 },
{ id: 4, name: 'd', parentId: null },
{ id: 5, name: 'e', parentId: 2 },
]
const output = [
{ id: 1, name: 'a', items: [
{ id: 2, name: 'b', items: [
{ id: 5, name: 'e' }
]}
]},
{ id: 4, name: 'd', items: [
{ id: 3, name: 'c' }
]}
]
Hi guys! I'm very new to Ramda and taking hard time to get something done with it.
I need to transform input to output:
const input = {
// ... lots of props,
sections: [
{
heading: 'some header',
layoutRows: [
{
layoutItems: [
{
// ... lot of props,
editable: true,
label: 'item label',
layoutComponents: [
{
// ... lot of props,
label: 'component label',
name: 'component name',
type: 'Field'
}
]
}
]
}
]
}
]
}
const output = [
{
header: 'some header',
rows: [
{
label: 'item label',
groupable: false,
fields: ['component name1']
},
{
label: 'item label',
groupable: true,
fields: ['component name1']
}
]
}
]
// mine ugly solution
const convertLayout = pipe(
prop('sections'),
map(
({heading: header, layoutRows}) =>
({
header,
rows: pipe(
chain(prop('layoutItems')),
filter(propEq('editable', true)),
map(
({label, layoutComponents}) => ({
label,
groupable: layoutComponents.length > 1,
fields: pipe(
filter(propEq('type', 'Field')),
map(prop('name'))
)(layoutComponents)
})
)
)(layoutRows)
})
)
)
convertLayout(input)
My solution does not looks like something readable at all
Hi
I am trying to convert an object to a nested structure
giving an example below:
input:
{
'foo.bar': 'baz',
'foo.baz': 2,
'bar.foo': 1,
'bar.baz.0': 1,
'bar.baz.1': 2
baz: 3,
}
output:
{
foo: {
bar: 'baz',
baz: 2,
},
bar: {
foo: 1,
baz: [1,2]
},
baz: 3,
}
any reference for achieving this output?
Thanks
Can you verify that I did what I wanted? it looks like it works.
what I want at normalResult:
I want to multiply every element in array by 3
what I want at exitEarlyResult:
I want to multiply every element in array by 3 until I find element*3===6 at which point I want to stop computation and return false, if there are no elements like that then I want to return true
const transducer = map((x)=>{
// console.log(`x is ${x}`)
return x*3
})
const iterator = (acc, val) => acc.concat([val])
const initialValue = [];
const col = [1,2,3,4,5]
const normalResult = transduce(transducer, iterator, initialValue, col)
const stop = (acc, val) => {
// console.log(`acc ${JSON.stringify(acc)} val ${val}}`)
return equals(6, val) ? reduced(false) : true
}
const exitEarlyResult = transduce(transducer, stop, initialValue, col)
converge(identity, identity)
?
What is the simplest way to remove properties, which have null values?
So
const a = { hello: 'world', nobody: null };
const b = ??? ; //
b == { hello: 'world'};
Hi. I'm new to FP and Ramda. I'm using Typescript and running into a bit of a developer experience problem with pipe, and I'm wondering if there's a more elegant way to express what I'm writing.
return pipe<
[QuestLog],
QuestLog,
QuestLog,
QuestLog,
QuestLog,
QuestLog,
QuestLog,
QuestLog,
QuestLog
>(
createUser("dan"),
createUser("rob"),
createUser("estaban"),
createUser("colin"),
createUser("matt"),
createCampaign(campaignUuid, "The Rainbow Sands", "matt"),
addUserToCampaign(campaignUuid, "dan"),
addUserToCampaign(campaignUuid, "rob"),
addUserToCampaign(campaignUuid, "estaban"),
addUserToCampaign(campaignUuid, "colin")
)({
campaigns: [],
users: [],
});
It seems that pipe cannot infer the types of my mutation functions, each of which are QuestLog -> QuestLog
. To handle this, I have to write out a huge cluster of types in the template.
Is there either a way to have pipe infer the type appropriately, or a way to tell it that all arguments will be of the same type, so I only have to specify it once?
This question is related to the Ramda Docs and Html sematics.
The Ramda Docs page has headers like "add", that when clicked navigate within the current window to the add function.
Looking at the html:
<h2>
<a tabindex="2" class="name" href="#add">add</a>
<span class="pull-right">
<span class="label label-category">Math</span>
<a target="_blank" title="View source on GitHub" href="https://github.com/ramda/ramda/tree/v0.28.0/source/add.js"><small class="glyphicon glyphicon-new-window"></small></a>
</span>
</h2>
Mdn docs for the a tag say using the ID creates the link,
<p><a href="#Section_further_down">
Jump to the heading below
</a></p>
<h2 id="Section_further_down">Section further down</h2>
Yet in Ramda docs there is no ID, so how does it still work?
Hi everyone, I'm new to Ramda (and FP) and was hoping for some help with implementing some code with Ramda.
I have an object o
with current value of { foo: [{ value: "bar" }] }
.
I would like to create a function that appends an array of newData
to one of the child arrays of existingData
based on a dynamic criteria (in this case, I just take the first key of existingData
).
Without Ramda, it looks like this:
const o = { foo: [{ value: "bar" }] };
function pushToFirstKey(newData, existingData) {
const key = Object.keys(existingData)[0]
return {
...existingData,
[key]: [...existingData[key], ...newData]
}
}
pushToFirstKey([{ value: "baz" }], o);
// Result: {"foo": [{"value": "bar"}, {"value": "baz"}]}
My attempt with Ramda looks like this:
const o = { foo: [{ value: "bar" }] };
const pushToFirstKeyFP = (newData, existingData) =>
R.compose(
R.assocPath([R.head(R.keys(existingData))], R.__, existingData),
R.concat(R.prop(R.head(R.keys(existingData)), existingData))
)(newData);
pushToFirstKeyFP([{ value: "baz" }], o);
// Result: {"foo": [{"value": "bar"}, {"value": "baz"}]}
Which I suspect could be better written.
Does anyone have suggestions for me?
const mergeArraysAtFirstKey = (arr, obj) => (
modify(head(keys(obj)),
concat(arr))
);
I should have mentioned that this is just for illustration, I wanted to understand how exactly it works, so optimisations like that wouldn't work in my case.
I also didn't hope to get any answer after so long, since then for my case I also considered generators, but they have overhead and are slower when entire collection must be computed. What is the performance price of using transducers? They look a bit like generators, object that has a function. So I guess it could be same as generators.
I don't know if this is useful information, but I found an example where R.flatten() on an array of objects with a length property does not work as intended.
In this example, R.flatten(array) and array.flat() produce different results.
This behavior is probably due to the fact that in the implementation of _isArrayLike(), an object with a length property of 0 is considered an array.
(I found this while using CodeMirror; CodeMirror's Line object has a length property which signifies how many chars the Line has.)
if (x.length === 0) { return true; }
there is specific case for such object which makes it array like so I guess it works as intended.
{0: 'a', length: 1}
this is array like, same "array" with zero items should look like {length: 0}
Hi, I would like to know how to make a check inside the pipelines to avoid the process to throw exception.
For example:
const isTypeDensity = R.propEq('type', 'density');
const getDensity = R.pipe(
R.find(isTypeDensity),
R.pick(['value', 'error', 'measureUnit'])
)
when I pass a null argument to getDenisty it will throw an error but also if i pass an empty array (or an array with all alements that don't match the predicate) will throw an error because R.pick will take a null value. How can i fix this issue?
with vanilla javascript i can easily do with something like this:
myArray?.find()?. etc..
thank you for the help.
you should somehow stop when find is undefined, there is no reason to do the pick at that point
const isTypeDensity = R.propEq('type', 'density');
const data = [{type: 'density', value: '1'}];
const wrongData = [{type: 'abc'}]
const density = //find(isTypeDensity, data);
find(isTypeDensity, wrongData);
const userPick = pick(['value', 'error', 'measureUnit']);
ifElse(identity, userPick, F)(density);
so something like this works, I can't say that I like it.
it is also not clear what u want returned when it fails.
:point_up: Edit: you should somehow stop when find is undefined, there is no reason to do the pick at that point
const isTypeDensity = R.propEq('type', 'density');
const data = [{type: 'density', value: '1'}];
const wrongData = [{type: 'abc'}]
const density = //find(isTypeDensity, data);
find(isTypeDensity, wrongData);
const userPick = pick(['value', 'error', 'measureUnit']);
ifElse(identity, userPick, F)(density);
// or
when(identity, userPick)(density);
so something like this works, I can't say that I like it.
it is also not clear what u want returned when it fails.
var data_array = [1, 2, 3,'hot', 4, 5, 6]
var D = x=> new Dataflow()
var data = D()
.filter(Number.isInteger)
.filter(x => x % 2)
.map(x => x * 2)
// these two filters and map get transduced automagically
.append('test')
.filter(x=> x>3)
.map(x => x * 2)
// filter + map = separate transducer
.prepend('maroon')
.compute(data_array)
// [ 'maroon', 5 ]
Hello everyone, I'm using Ramda with TS and can't get the mapping of objects to work:
const double = (x: number) => x * 2;
R.map(double, { aKey: 1 });
Complains that no overload can be found:
No overload matches this call.
Overload 1 of 6, '(fn: (x: number) => number, list: readonly number[]): number[]', gave the following error.
Argument of type '{ aKey: number; }' is not assignable to parameter of type 'readonly number[]'.
Object literal may only specify known properties, and 'aKey' does not exist in type 'readonly number[]'.
Overload 2 of 6, '(fn: (x: number) => never, list: { aKey: number; }): unknown', gave the following error.
Argument of type '(x: number) => number' is not assignable to parameter of type '(x: number) => never'.
Type 'number' is not assignable to type 'never'.
Overload 3 of 6, '(fn: (x: number) => number, obj: Functor<number>): Functor<number>', gave the following error.
Argument of type '{ aKey: number; }' is not assignable to parameter of type 'Functor<number>'.
Property 'map' is missing in type '{ aKey: number; }' but required in type '{ [key: string]: any; map: <B>(fn: (a: number) => B) => Functor<B>; }'.ts(2769)