【问题标题】:Filter collection based on values in array in Ramda根据 Ramda 中数组中的值过滤集合
【发布时间】:2018-05-03 17:46:58
【问题描述】:

我有一个唯一值数组:

const array = [1, 2, 4]

我有一组独特的对象:

const collection = [
  { type: 1, eyes: 'blue'},
  { type: 2, eyes: 'brown'},
  { type: 3, eyes: 'green'},
  { type: 4, eyes: 'blue'}
]

使用 Ramda 如何从 collection 中提取所有对象,其中类型包含在 array 中?

预期结果:

[
  { type: 1, eyes: 'blue'},
  { type: 2, eyes: 'brown'},
  { type: 4, eyes: 'blue'}
]

【问题讨论】:

  • 这不是 ramda,但您可以定义一个过滤器函数,采用 getter 和 compare 函数并组合其中的多个来创建强大的数组过滤器。示例here

标签: javascript ramda.js


【解决方案1】:

使用R.innerJoin():

const array = [1, 2, 4]
const collection = [{ type: 1, eyes: 'blue'},{ type: 2, eyes: 'brown'}, { type: 3, eyes: 'green'}, { type: 4, eyes: 'blue'}]

const joinByType = R.innerJoin(
  (o, type) => o.type === type
)

const result = joinByType(collection, array)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>

使用R.propEq()type 属性与数组中的类型id 进行比较,以更简单的方式使用相同的方法。我们需要使用R.flip(),因为innerJoin 在要比较的值之前传递对象。

const array = [1, 2, 4]
const collection = [{ type: 1, eyes: 'blue'},{ type: 2, eyes: 'brown'}, { type: 3, eyes: 'green'}, { type: 4, eyes: 'blue'}]

const joinByType = R.innerJoin(R.flip(R.propEq('type')))

const result = joinByType(collection, array)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>

【讨论】:

  • 如果有人缺少 innerJoin 的 typescript 类型,只需添加以下内容: declare module 'ramda' { interface Static { innerJoin(fn: (v: U, p: T) = > 布尔值,x1: U[], x2: T[]): U[]; } }
【解决方案2】:

没有 ramda

collection.filter(item => array.includes(item.type))

【讨论】:

    【解决方案3】:

    我认为 Mukesh Soni 的答案正是您所需要的。在 Ramda 中,它可能读作 filter(p => array.includes(p.type), collection),但大致相同。

    但 Ramda 完全是关于函数,并创建可重用且灵活的函数来满足您的需求。我至少会考虑写这样的东西:

    const {curry, filter, contains, prop} = R
    
    const collection = [{ type: 1, eyes: 'blue'},{ type: 2, eyes: 'brown'}, { type: 3, eyes: 'green'}, { type: 4, eyes: 'blue'}]
    const array = [1, 2, 4]
    
    const filterBy = curry((propName, selectedValues, collection) => 
      filter(e => contains(prop(propName, e), selectedValues), collection))
    
    const newCollection = filterBy('type', array, collection)
    
    console.log(newCollection)
    <script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>

    我什至可能更进一步,允许任意转换函数,而不仅仅是prop

    const filterBy = curry((transform, selectedValues, collection) => 
      filter(e => selectedValues.includes(transform(e)), collection))
    
    filterBy(prop('type'), array, collection)
    

    但这些抽象通常只有在您希望在您的应用程序中以其他方式使用它们时才有用。如果这是您使用要匹配的值列表来过滤集合的唯一地方,那么几乎没有理由使用任何可重用函数。

    【讨论】:

      猜你喜欢
      • 2020-02-01
      • 1970-01-01
      • 2018-12-11
      • 2020-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-08
      • 1970-01-01
      相关资源
      最近更新 更多