I am trying to update a value in an array in a nested object structure using Ramda.
I want to update the value prop of the object in C
with the name blah
const o = {
A: {
B: {
C: [
{name: 'blah', value: 'blah'},
{name: 'vtha', value: 'blah'},
]
}
}
}
I've been plying with lenses, but it seems quite verbose and I figure I am doing it wrong.
Ideally, I would love something that returns a new object.
const res = fn(o)
{
A: {
B: {
C: [
{name: 'blah', value: 'vtha'}
{name: 'vtha', value: 'blah'},
]
}
}
}
I am trying to update a value in an array in a nested object structure using Ramda.
I want to update the value prop of the object in C
with the name blah
const o = {
A: {
B: {
C: [
{name: 'blah', value: 'blah'},
{name: 'vtha', value: 'blah'},
]
}
}
}
I've been plying with lenses, but it seems quite verbose and I figure I am doing it wrong.
Ideally, I would love something that returns a new object.
const res = fn(o)
{
A: {
B: {
C: [
{name: 'blah', value: 'vtha'}
{name: 'vtha', value: 'blah'},
]
}
}
}
Share
Improve this question
edited Aug 6, 2017 at 7:57
Toby Hede
asked Aug 6, 2017 at 7:24
Toby HedeToby Hede
37.2k28 gold badges137 silver badges164 bronze badges
4
- 2 That's why proper types are more important than proper algorithms: you chose the weird structure, no wondering to modify it you need weird code. – zerkms Commented Aug 6, 2017 at 7:27
- It's data being returned from an api call. I can split this into sub elements and stitch it back together, but surely updating a value inside a structure is something that can be done in a reasonable way? – Toby Hede Commented Aug 6, 2017 at 7:40
-
Yep, do it in imperative way:
const obj = o.A.B.C.find(nested => nested.name === 'blah'); if (obj !== undefined) { obj.value = 'vtha'; }
it's easy to read and maintain. If necessary - wrap it in a function to look "functional". – zerkms Commented Aug 6, 2017 at 7:43 - 1 @zerkms That's why proper types are more important than proper algorithms. Indeed and additionally: Proper types naturally lead to proper algorithms. We need to talk more about types in Javascript. – user6445533 Commented Aug 6, 2017 at 14:13
3 Answers
Reset to default 4If you want to do it in immutable way it would be like
const fn = over(
R.lensPath(['A', 'B', 'C']),
R.map(
o => o.name === 'blah' ? R.assoc('value', 'vtha', o): o
)
)
Demo.
If you want to avoid manually defining functions by all means you could replace mapped function with
R.ifElse(
R.propEq('name', 'blah'),
R.assoc('value', 'blah'),
R.identity
)
But imho ternary operator looks more readable here.
You could try using filter and where, i wrote an example below.
const o = {
A: {
B: {
C: [
{name: 'blah', value: 'blah'},
{name: 'vtha', value: 'blah'},
]
}
}
};
var pred = R.filter(R.where({name: R.contains('blah')}));
pred(o.A.B.C);
To update the array in the object we need the path to the array. Then we can update the result with a lens and a helper function adjustIfSatisfies
const { propEq, identity, over, assoc, curry, lensPath, map, ifElse } = R
const o = {
A: {
B: {
C: [
{name: 'blah', value: 'blah'},
{name: 'vtha', value: 'blah'},
]
}
}
}
const adjustIfSatisfies = curry(
(pred, updateFn, samples) => {
return map(ifElse(pred, updateFn, identity), samples)
}
)
const result = over(
lensPath(['A', 'B', 'C']),
adjustIfSatisfies(
propEq('name', 'blah'),
assoc('value', 'vtha')
),
o
)
console.log(result)
<script src="https://cdnjs.cloudflare./ajax/libs/ramda/0.27.1/ramda.min.js"></script>
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745346669a4623581.html
评论列表(0条)