简体   繁体   English

过滤器和 map 阵列与 Ramda

[英]Filter & map an array with Ramda

I am using Ramda to get the teams with 'Prem League' in their categories array.我正在使用 Ramda 在他们的类别数组中获得'Prem League'的球队。 My code looks like the following and it works.我的代码如下所示,并且可以正常工作。

import { pipe, map, filter } from 'ramda'   

const teams = [
  {name: 'Liverpool', id: '1', categories: ['Prem League']},
  {name: 'Man Utd', id: '2', categories: ['Blue Square']},
  {name: 'Sheff Utd', id: '2', categories: ['Prem League']},
]

const getTeamOptions = pipe(
    filter((team) => team.categories.includes('Prem League')),
    map((team) => ({ label: team.name, value: team.id }))
);

getTeamOptions(teams)

However I want to remove team as the argument for filter and map .但是我想删除team作为 filter 和map的参数。

I tried the following but got prop(...).includes is not a function我尝试了以下但得到prop(...).includes is not a function

filter(prop('categories').includes('Prem League')),

Ideally I would try and remove team from map too but maybe this is not necessary.理想情况下,我也会尝试从map中删除team ,但也许这不是必需的。

The reason for these changes is that I have been following this course and it advises prop etc as best practices.这些变化的原因是我一直在学习这门课程,它建议prop等作为最佳实践。

You can use R.includes to check for the existence of the value.您可以使用 R.includes 来检查该值是否存在。 You can generate the new object using R.applySpec:您可以使用 R.applySpec 生成新的 object:

 const { pipe, filter, prop, includes, map, applySpec } = R; const getTeamOptions = val => pipe( filter(pipe(prop('categories'), includes(val))), map(applySpec({ label: prop('name'), value: prop('id') })) ); const teams = [{"name":"Liverpool","id":"1","categories":["Prem League"]},{"name":"Man Utd","id":"2","categories":["Blue Square"]},{"name":"Sheff Utd","id":"2","categories":["Prem League"]}]; const result = getTeamOptions('Prem League')(teams); console.log(result);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js"></script>

this would also help you solve it with ramda in a point free fashion...这也将帮助您以无点方式使用 ramda 解决它...

 const hasPremLeague = R.where({ categories: R.includes('Prem League') }); const toOption = R.applySpec({ label: R.prop('name'), value: R.prop('id') }); const getTeamOptions = R.into([], R.compose( R.filter(hasPremLeague), R.map(toOption), )); // --- const teams = [ {name: 'Liverpool', id: '1', categories: ['Prem League']}, {name: 'Man Utd', id: '2', categories: ['Blue Square']}, {name: 'Sheff Utd', id: '2', categories: ['Prem League']}, ]; console.log( getTeamOptions(teams), );
 <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js"></script>

const premLeague = R.equals('Prem League');
const premLeagueInArray = R.any(premLeague);
const categories = R.path(['categories']);
const isPremLeagueInArray = R.pipe(
  categories,
  premLeagueInArray,
);

const teams = [
  { name: "Liverpool", id: "1", categories: ["Prem League"] },
  { name: "Man Utd", id: "2", categories: ["Blue Square"] },
  { name: "Sheff Utd", id: "2", categories: ["Prem League"] },
];
const premLeagueTeam = [
  { name: "Liverpool", id: "1", categories: ["Prem League"] },
  { name: "Sheff Utd", id: "2", categories: ["Prem League"] },
];

const transducer = R.compose(R.filter(isPremLeagueInArray));
const getPremLeagueTeam = R.transduce(transducer, R.flip(R.append), []);

R.equals(getPremLeagueTeam(teams), premLeagueTeam);

You should consider a non-Ramda option too.您也应该考虑使用非 Ramda 选项。

This may or may not be an abuse of Array#flatMap but I find it acceptable: filter + map = flatMap这可能是也可能不是Array#flatMap的滥用,但我认为这是可以接受的:filter + map = flatMap

Let's say you want to add 10 to even numbers and exclude odd numbers:假设您想将 10 添加到偶数排除奇数:

[1, 2, 3, 4].flatMap(n => n % 2 === 0 ? n + 10 : []);
//=> [12, 14]

There is also a point to be made about pointfree style.关于无点风格,还有一点需要说明。 It's nice, but sometimes it gets in the way.这很好,但有时它会妨碍您。 For example it doesn't allow you to leverage some nice ES6 constructs.例如,它不允许您利用一些不错的 ES6 结构。 For example destructuring:例如解构:

const getTeamOptions =
  teams =>
    teams.flatMap
      ( ({name: label, id: value, categories}) =>
          categories.includes('Prem League')
            ? { label, value }
            : []
      );

getTeamOptions
  ( [ {name: 'Liverpool', id: '1', categories: ['Prem League']}
    , {name: 'Man Utd', id: '2', categories: ['Blue Square']}
    , {name: 'Sheff Utd', id: '2', categories: ['Prem League']}
    ]
  );

//=> [ {label: "Liverpool", value: "1"}
//=> , {label: "Sheff Utd", value: "2"} ]

For completeness, here's a variant using Array#reduce :为了完整起见,这里有一个使用Array#reduce的变体:


const getTeamOptions =
  teams =>
    teams.reduce
      ( (acc, {name: label, id: value, categories}) =>
          categories.includes('Prem League')
            ? (acc.push({ label, value }), acc)
            : acc
      , []
      );

Don't get me wrong!不要误会我的意思! Ramda is absolutely amazing .拉姆达绝对是惊人的 When I first met this library I wanted to rewrite all my code with it, then I discovered pointfree style and rewrote everything again.当我第一次遇到这个库时,我想用它重写我的所有代码,然后我发现了无点风格并再次重写了所有代码。 In the end I completely lost mental control of my code and that's a problem.最后,我完全失去了对代码的精神控制,这是一个问题。 You should only use Ramda when it serves you well.你应该只在 Ramda 为你服务的时候才使用它。 In this case you could do without to be honest.在这种情况下,你可以不诚实。

I love to do this in composable way, but currently you are using pipe so I do this with pipe for consitency.我喜欢以可组合的方式执行此操作,但目前您使用的是pipe ,所以我使用pipe执行此操作以保持一致性。 Below is a worked solution下面是一个有效的解决方案

 const teams = [ { name: 'Liverpool', id: '1', categories: ['Prem League'] }, { name: 'Man Utd', id: '2', categories: ['Blue Square'] }, { name: 'Sheff Utd', id: '2', categories: ['Prem League'] } ] const getTeamOptions = pipe( filter( pipe( prop('categories'), includes('Prem League') ) ), map( pipe( props(['name', 'id']), zipObj(['label', 'value']) ) ) ) console.log(getTeamOptions(teams))
 <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js"></script> <script>const { pipe, map, filter, prop, includes, zipObj, props } = R</script>

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

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