Filter collection based on values in array in Ramda

不问归期 提交于 2019-12-11 04:26:57

问题


I have an array of unique values:

const array = [1, 2, 4]

I have a collection of unique objects:

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

Using Ramda how do I extract all the objects from collection where type is included in array?

Expected outcome:

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

回答1:


Use 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>

The same method in a more ramdaish way using R.propEq() to compare the type property with the type id from the array. We need to use R.flip() because innerJoin passes the object before the the value to compare to.

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>



回答2:


Without ramda

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



回答3:


I think the answer from Mukesh Soni is what you need for this. In Ramda, it might read filter(p => array.includes(p.type), collection), but that's much the same.

But Ramda is all about functions, and creating reusable and flexible functions to handle your needs. I would at least consider writing something like this:

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>

I might even go one step further, and allow for an arbitrary transformation function, rather than just prop:

const filterBy = curry((transform, selectedValues, collection) => 
  filter(e => selectedValues.includes(transform(e)), collection))

filterBy(prop('type'), array, collection)

But abstractions such as these are generally only helpful if you expect to make other use of them across your application. If this is the only place where you use a list of values to match with in order to filter a collection, then there is little reason for any reusable function.



来源:https://stackoverflow.com/questions/50161078/filter-collection-based-on-values-in-array-in-ramda

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!