Reputation: 5797
I have two array of JSON objects
const array_one = [
{id:'a',city:'Sydney',offer:'HAS'},
{id:'b',city:'Sydney',offer:'AHR'},
{id:'c',city:'Perth',offer:'AHR'},
];
const array_two = [
{id:'a',html:''},
{id:'b',html:''},
{id:'c',html:''},
{id:'d',html:''},
{id:'e',html:''},
];
Update the array_two, add new property "isEligible" = true/false, based on array_one condition (where city = 'Sydney' and offer = 'AHR')
const array_two = [
{id:'a',html:'', isEligible: false},
{id:'b',html:'', isEligible: true},
{id:'c',html:'', isEligible: false},
{id:'d',html:'', isEligible: false}, // default false
{id:'e',html:'', isEligible: false},
];
Tried the below:
array_two.forEach(arrayTwoItem=> {
let arrayOneItem= R.find(
R.propEq('id', arrayTwoItem.id)),
array_one,
);
// eslint-disable-next-line no-param-reassign
arrayTwoItem.isElibible= R.allPass[
R.equals(
'Sydney',
arrayOneItem.city,
),
R.equals(
'AMR',
arrayOneItem.offer,
)]
});
How to avoid the lint error , param reassign? how to completely solve using ramda?
tried R.assocPath, not worked.
Upvotes: 0
Views: 102
Reputation: 18891
I'd write a function that takes a predicate and the array to update:
const eligibility =
(city, offer, xs) => id =>
any(whereEq({id, city, offer}), xs);
const up =
pred => map(o =>
({...o, isEligible: pred(o.id)}));
console.log(
up(eligibility('Sydney', 'AHR', array_one))(array_two)
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.28.0/ramda.min.js"></script>
<script>const {map, any, whereEq} = R;</script>
<script>
const array_one =
[ {id:'a', city:'Sydney', offer:'HAS'}
, {id:'b', city:'Sydney', offer:'AHR'}
, {id:'c', city:'Perth' , offer:'AHR'}];
const array_two =
[ {id:'a', html:''}
, {id:'b', html:''}
, {id:'c', html:''}
, {id:'d', html:''}
, {id:'e', html:''}];
</script>
Upvotes: 1
Reputation: 50787
One approach would be to write a function that looks like (city, offer) => (array_one) => (array_two) => updated version of array_two
, one which you later can configure with "Sydney"
and "AHR"
. It might look like this:
const matchId = pipe (eqProps ('id'), find)
const update = (city, offer) => pipe (
(xs) => (y, m = matchId (y) (xs)) =>
assoc ('isEligible', Boolean (m) && m .city == city && m .offer == offer) (y),
map
)
const array_one = [{id: 'a', city: 'Sydney', offer: 'HAS'}, {id: 'b', city: 'Sydney', offer: 'AHR'}, {id: 'c', city: 'Perth', offer: 'AHR'}]
const array_two = [{id: 'a', html: ''}, {id: 'b', html: ''}, {id: 'c', html: ''}, {id: 'd', html: ''}, {id: 'e', html: ''}]
console .log (update ('Sydney', 'AHR') (array_one) (array_two))
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.28.0/ramda.min.js"></script>
<script> const {pipe, eqProps, find, assoc, map} = R </script>
matchId
is a simple helper, and could be in-lined, but I find it more readable like this. The main function creates a mapping function by passing array_one
into (xs) => (y, m = ...) => ...
, and then passes that mapping function into map
, ready for array_two
. The mapping function checks for a record in array_one
that has a matching id
, and then uses assoc ('isElgible', ...)
to return a value with the new property.
I'm sure that if we tried, we could make that predicate used for isEligible
point-free, but I think this reads well like this, and I wouldn't bother.
Upvotes: 1