将功能包装到另一个功能中

时间:2015-03-10 17:50:40

标签: javascript functional-programming lodash

我有使用lodash通过object属性对对象数组进行排序的代码。这很简单:

_.sortBy(data.cycles, "id");

但是,我发现data.cycles[].id可能是一个字符串,因此我必须先将每个属性转换为数字,然后再将其传递给_.sortBy。这有什么优雅的方式吗?我想我应该以某种方式结合_.propertyparseInt,但我不知道如何。

data.cycles可能如下所示:

[
  {
    "id": "20",
    "name": "John"
  },
  {
    "id": "15",
    "name": "Sarah"
  },
  {
    "id": "158",
    "name": "Bill"
  },
  {
    "id": "-6",
    "name": "Jack"
  },
  {
    "id": "59",
    "name": "Bob"
  }
]

2 个答案:

答案 0 :(得分:2)

我会按如下方式撰写sortBy()回调:

var collection = [
    { id: '20', name: 'John' },
    { id: 15, name: 'Sarah' },
    { id: 158, name: 'Bill' },
    { id: '-6', name: 'Jack' },
    { id: 59, name: 'Bob' }
];

_.sortBy(collection, _.flow(_.property('id'), parseInt));
// →
// [
//   { id: '-6', name: 'Jack' },
//   { id: 15, name: 'Sarah' },
//   { id: '20', name: 'John' },
//   { id: 59, name: 'Bob' },
//   { id: 158, name: 'Bill' }
// ]

当您想要从许多函数中组合回调函数时,flow()函数很有用,它只是将输出转发到行中的下一个函数。 property()函数返回一个函数,该函数从其参数中获取指定的属性名称。这是id,并传递给parseInt()

我们实际上是在同一时间进行映射和排序。这具有效率优势,除了是单行之外:它不必遍历整个集合两次。这对于较小的集合来说并不是什么大问题,但是对于较大的集合,其影响是显而易见的。

答案 1 :(得分:1)

您可能希望先运行map并修改id,然后进行排序。

在vanilla JS中,它看起来像:

function mapFn(item){
  item.id = parseInt(item.id, 10);
  return item;
}

var sortedCycles = data.cycles.map(mapFn).sort(sortFn);

在lodash,你可以:

var sortedCycles = _.sortBy(_.map(data.cycles, mapFn), 'id');
// or
var sortedCycles = _.chain(data.cycles).map(mapFn).sortBy('id').value()