构建用户友好的API以按多个标准排序

时间:2017-04-11 12:26:20

标签: scala sorting

我想知道是否可以构建一个允许同时按多个标准排序的API。我知道可以对元组进行排序,而且我没有寻找替代解决方案,我的问题也是为了提高我对目前面临的问题的了解。

目前我的代码如下:

object MultiSort {

  case class SortByCriteria[ItemType, SortType](
    sortBy: ItemType => SortType,
    ordering: Ordering[SortType]
  )

  def sort[ItemType](items: List[ItemType])(sortByList: List[SortByCriteria[ItemType, _]]) = {
    sortByList.foldRight(items) { case (sortByCriteria, acc) =>
      acc.sortBy(item => sortByCriteria.sortBy(item)(sortByCriteria.ordering)
    }
  }

}

Because sortBy is stable,我应该可以在raw中应用多个sortBy并按多个标准排序获取结果。不幸的是,我努力用类型系统表达我想要的东西,因为我的标准列表是异质的List[SortByCriteria[ItemType, _]]

所以,我想知道如何连续应用多个sortBy并保持类型系统满意

1 个答案:

答案 0 :(得分:1)

这个问题在scala中很常见。当您将所有SortByCriteria放入List时,您将丢失特定类型,因为该列表会强制所有项目为公共超类型。诀窍是将需要特定于类型的知识的代码移动到仍然具有该信息的编译单元:

case class SortByCriteria[ItemType, SortType](
  sortBy: ItemType => SortType,
  ordering: Ordering[SortType]
) {
  def sort (items: List[ItemType]): List[ItemType] = 
    // this is the line that needs to know the `SortType`
    // so we move it to the code that has that information
    items.sortBy(sortBy)(ordering)
}

// not tested
// not sure about this, but hopefully gets the point accross
def sort[ItemType](items: List[ItemType])(sortByList: List[SortByCriteria[ItemType, _]]) = {
  sortByList.foldRight(items) { case (sortByCriteria, acc) =>
    sortByCriteria.sort(acc)
  }
}