繁体   English   中英

Ramda — 如果一个数组的元素与另一个数组中的元素匹配,则更新它们

[英]Ramda — Update elements of an array if they match elements from another array

我有两个 JSON 对象数组

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:''},
];

更新 array_two,添加新属性“isEligible” = true/false,基于 array_one 条件(其中 city = 'Sydney' 和 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},
    ];

试过以下:

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,
    )]
 });

如何避免 lint 错误,参数重新分配? 如何使用 ramda 彻底解决?

试过 R.assocPath,没用。

一种方法是编写一个看起来像(city, offer) => (array_one) => (array_two) => updated version of array_two ,稍后您可以使用"Sydney""AHR"对其进行配置。 它可能看起来像这样:

 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是一个简单的助手,可以内联,但我发现它像这样更具可读性。 主函数通过将array_one传递给(xs) => (y, m = ...) => ...创建一个映射函数,然后将该映射函数传递给map ,为array_two做好准备。 映射函数检查array_one中具有匹配id的记录,然后使用assoc ('isElgible', ...)返回具有新属性的值。

我敢肯定,如果我们尝试,我们可以使用于isEligible的谓词无点,但我认为这样读起来很好,我不会打扰。

我会编写一个函数,该函数需要一个谓词和要更新的数组:

 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>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM