-->

ramda function javascript on arrays

2019-08-24 20:59发布

问题:

const censusMembers = Object.freeze([
    {
        id: 1,
        name: 'Bob'
    }, {
        id: 2,
        name: 'Sue'
    }, {
        id: 3,
        name: 'Mary',
        household_id: 2
    }, {
        id: 4,
        name: 'Elizabeth',
        household_id: 6
    }, {
        id: 5,
        name: 'Tom'
    }, {
        id: 6,
        name: 'Jill'
    }, {
        id: 7,
        name: 'John',
        household_id: 6
    }
]);

In this array, A dependent can be determined by the presence of a household_id. The household_id is a reference to the ID of the employee that that member is a depended of (ex in the censusMembers list 'Mary' is a dependent of 'Sue')

How to build a function that takes in an id and the array of members(census members) and returns all dependents that belong to the user that has that id.

If the id is of a dependent, or isn't in the censusMember array then the function should return null.

If there are no dependents then the function should return an empty arrray.

for example:

if I give input as id 6 then output shoul be

[
{"id":4,"name":"Elizabeth","household_id":6}, 
{"id":7,"name":"John","household_id":6}
]

回答1:

Here is code that seems to do what you would like:

const {curry, find, propEq, has, filter} = R

const householdMembers = curry((census, id) => {
  const person = find(propEq('id', id), census);
  return person 
    ? has('household_id', person)
      ? null
      : filter(propEq('household_id', id), census)
    : null
})


var censusMembers = Object.freeze([
  {id: 1, name: 'Bob'}, 
  {id: 2, name: 'Sue' }, 
  {id: 3, name: 'Mary', household_id: 2 }, 
  {id: 4, name: 'Elizabeth', household_id: 6},
  {id: 5, name: 'Tom'}, 
  {id: 6, name: 'Jill'}, 
  {id: 7, name: 'John', household_id: 6}
])

const householders = householdMembers(censusMembers)

console.log(householders(6))
//=> [
//     {id: 4, name: 'Elizabeth','household_id': 6},
//     {id: 7, name: 'John', 'household_id': 6}
//   ]
console.log(householders(7))  //=> null
console.log(householders(8))  //=> null
console.log(householders(5))  //=> []
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>

But I would suggest that you might want to rethink this API. The empty array is a perfectly reasonable result when nothing is found. Making it return null for some of these cases makes the output much harder to use. For instance, if you wanted to retrieve the list of names of household members, you could simply write const householderNames = pipe(householders, prop('name')). Or you could do this if your function always returned a list.

Having a single function return multiple types like this is much harder to understand, and much, much harder to maintain. Note how much simpler the following version is, one that always returns a (possibly empty) list:

const members = curry((census, id) => filter(propEq('household_id', id), census))