Javascript 在Coffeescript中,如何按一个属性对对象数组进行分组?

Javascript 在Coffeescript中,如何按一个属性对对象数组进行分组?,javascript,arrays,coffeescript,Javascript,Arrays,Coffeescript,假设我有一个这样的对象数组: var array = [ {name:"aaa", height:"20"}, {name:"bbb", height:"100"}, {name:"ccc", height:"20"}, {name:"ddd", height:"20"}, {name:"eee", height:"100"}, ] group_by_height = (groups, obj) -> groups[obj.height]

假设我有一个这样的对象数组:

var array = [
    {name:"aaa", height:"20"},
    {name:"bbb", height:"100"},
    {name:"ccc", height:"20"},
    {name:"ddd", height:"20"},
    {name:"eee", height:"100"},
]
group_by_height = (groups, obj) ->
    groups[obj.height] ?= [ ]
    groups[obj.height].push(obj)
    groups
grouped_obj = array.reduce(group_by_height, { })
grouped_by_height = (v for k, v of grouped_obj)
在本例中,我想按高度对其进行分组,因此我最终得到一个具有组名的不同数组,然后该组中的每个项目如下所示:

var grouped_by_height = [
    [{name:"aaa", height:"20"}, {name:"ccc", height:"20"}, {name:"ddd", height:"20"}],
    [{name:"bbb", height:"100"}, {name:"eee", height:"100"}]
]

我已经用JS/jQuery编写了一个很长的解决方案,但我想知道是否有一种快速而简单的方法可以做到这一点,那就是Coffeescript。

我认为Coffeescript中没有什么特别的东西可以帮到你(或者至少没有任何东西可以处理难处理的部分)。我可能会使用
Array.prototype.reduce
这样做:

var array = [
    {name:"aaa", height:"20"},
    {name:"bbb", height:"100"},
    {name:"ccc", height:"20"},
    {name:"ddd", height:"20"},
    {name:"eee", height:"100"},
]
group_by_height = (groups, obj) ->
    groups[obj.height] ?= [ ]
    groups[obj.height].push(obj)
    groups
grouped_obj = array.reduce(group_by_height, { })
grouped_by_height = (v for k, v of grouped_obj)
但是,这并不能保证按高度分组的
中的任何特定顺序,但可以通过添加排序步骤来解决这一问题:

by_height = (a, b) -> +a[0].height - +b[0].height
group_by_height = (v for k, v of grouped_obj).sort(by_height)

您将对数组进行排序,这样
a
b
将是数组,因此
[0]
将查看第一个元素。一元
+
运算符用于将字符串高度转换为数字高度,以便它们能够以您可能期望的方式进行比较。

这就是我能够想到的。正如mu所说的太短了,咖啡脚本中没有魔力,但有一些内置的东西可以帮助它。唯一的问题是编译后的js版本最终会比用纯js编写的版本长

groupByKey = (array, key) ->
  grouped = {}
  for obj in array
    grouped[obj[key]] ?= []
    grouped[obj[key]].push obj
  Object.keys(grouped).map (group) ->
    grouped[group]
自己尝试一下:

array = [
  {
    name: 'aaa'
    height: '20'
  }
  {
    name: 'bbb'
    height: '100'
  }
  {
    name: 'ccc'
    height: '20'
  }
  {
    name: 'ddd'
    height: '20'
  }
  {
    name: 'eee'
    height: '100'
  }
]

groupByKey = (array, key) ->
  grouped = {}
  for obj in array
    grouped[obj[key]] ?= []
    grouped[obj[key]].push obj
  Object.keys(grouped).map (group) ->
    grouped[group]

console.log groupByKey(array, 'height')
输出为:

[
  [
    { 
      name: 'aaa',
      height: '20' 
    },
    { 
      name: 'ccc',
      height: '20' 
    },
    { 
      name: 'ddd',
      height: '20' 
    } 
  ],
  [ 
    { 
      name: 'bbb',
      height: '100'
    },
    { 
      name: 'eee',
      height: '100' 
    }
  ]
]

CoffeeScript只是JavaScript的一种不同语法。除了列表理解的速记之外,它不提供任何数据操作机制。