Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sorting 如何按属性值对coffeescript映射对象进行排序?_Sorting_Coffeescript - Fatal编程技术网

Sorting 如何按属性值对coffeescript映射对象进行排序?

Sorting 如何按属性值对coffeescript映射对象进行排序?,sorting,coffeescript,Sorting,Coffeescript,我有一个文章列表,每个文章都有一个简单的标签字符串数组。我这样计算标签频率: 计数标签频率 getTags = (articles) -> tags= {} for article in articles for tag in article.Tags tags[tag] = (tags[tag] or 0) + 1 tags 示例结果 生成的标记映射是一个对象,其属性名称设置为标记名称,属性值设置为频率计数,如下所示:

我有一个
文章列表
,每个文章都有一个简单的
标签字符串数组
。我这样计算标签频率:

计数标签频率

getTags = (articles) ->
    tags= {}
    for article in articles
        for tag in article.Tags
            tags[tag] = (tags[tag] or 0) + 1
    tags
示例结果

生成的
标记
映射是一个对象,其属性名称设置为
标记
名称,属性值设置为频率计数,如下所示:

问题

我想按属性值(频率计数)对该列表进行排序,如何实现这一点

注:如有需要,我很乐意更改计数方法

编辑1

感谢@LeonidBeschastny,我现在有了工作代码:

getTags = (articles) ->
    tags = {}
    for article in articles
        for tag in article.Tags
            tags[tag] = (tags[tag] or 0) + 1

    tags = do (tags) ->
        keys = Object.keys(tags).sort (a, b) -> tags[b] - tags[a]
        {name, count: tags[name]} for name in keys

    tags
您可以看到,我必须将未排序的
标记
映射对象投影到已排序的
{name:value}
对象的新数组中

这感觉像是太多的工作,我认为可能是原始未排序的对象是一个错误。有没有一种方法可以不经过这个中间步骤就获得排序数组

编辑2

感谢@hpaulj进行了一些时间测试,并发现与其他潜在解决方案(如运行的排序堆)相比,上面的代码实际上相当有效


我现在已经将此代码投入生产,并且运行良好。

您可以使用
Array::sort
对标记进行排序,然后重新生成
标记
对象:

tags = do (tags) ->
  res = {}
  keys = Object.keys(tags).sort (a, b) -> tags[b] - tags[a]
  for k in keys
    res[k] = tags[k]
  res
更新 至于插入顺序,
mu太短
是正确的,ECMA规范不保证
V8
为文字(非数字)键维护它,但我不太确定其他JS引擎

因此,正确的解决方案是使用阵列:

tags = do (tags) ->
  keys = Object.keys(tags).sort (a, b) -> tags[b] - tags[a]
  {name, count: tags[name]} for name in keys

您可以使用
Array::sort
对标记进行排序,然后重新生成
标记
对象:

tags = do (tags) ->
  res = {}
  keys = Object.keys(tags).sort (a, b) -> tags[b] - tags[a]
  for k in keys
    res[k] = tags[k]
  res
更新 至于插入顺序,
mu太短
是正确的,ECMA规范不保证
V8
为文字(非数字)键维护它,但我不太确定其他JS引擎

因此,正确的解决方案是使用阵列:

tags = do (tags) ->
  keys = Object.keys(tags).sort (a, b) -> tags[b] - tags[a]
  {name, count: tags[name]} for name in keys

使用
heapq
。这比简单的先计数再排序更复杂,但如果我们需要运行排序计数,这可能会很有用

使用Python的Coffeescript翻译

heap=require./heap'
#改编自
# http://docs.python.org/2/library/heapq.html#priority-队列实现说明
pq=[]#堆中排列的条目列表
entry_finder={}#任务到条目的映射
删除=“”
计数器=[0]
删除任务=(任务)->
#将现有任务标记为已删除。如果未找到,则返回null。
entry=entry\u finder[任务]
如果进入?
删除条目查找器[任务]
条目[entry.length-1]=已删除
返回条目
计数任务=(任务)->
条目=删除任务(任务)
如果进入?
[优先级、计数、计数]=条目
优先级+=1
其他的
计数器[0]+=1
计数=计数器[0]
优先级=1
条目=[优先级、计数、任务]
条目查找器[任务]=条目
堆推(pq,条目)
console.log h=['1','2','1','3','4','2','1']
用于h中的任务
计数任务(任务)
console.log条目\u finder
console.log pq
alist=heap.nlargest(pq,10)
对于列表中的x
[优先级、计数、任务]=x
如果是任务!=远离的
console.log任务、优先级、计数
产生

[ 'one', 'two', 'one', 'three', 'four', 'two', 'one' ]
{ three: [ 1, 3, 'three' ],
  four: [ 1, 4, 'four' ],
  two: [ 2, 2, 'two' ],
  one: [ 3, 1, 'one' ] }

[ [ 1, 1, '<removed-task>' ],
  [ 1, 2, '<removed-task>' ],
  [ 2, 1, '<removed-task>' ],
  [ 1, 3, 'three' ],
  [ 1, 4, 'four' ],
  [ 2, 2, 'two' ],
  [ 3, 1, 'one' ] ]

one 3 1
two 2 2
four 1 4
three 1 3
[‘一’、‘二’、‘一’、‘三’、‘四’、‘二’、‘一’]
{three:[1,3,'three'],
四:[1,4,'四'],
二:[2,2,'二'],
一:[3,1,'1']}
[ [ 1, 1, '' ],
[ 1, 2, '' ],
[ 2, 1, '' ],
[1,3,'三'],
[1,4,4'],
[2,2,'2'],
[3,1,'1']]
1 3 1
2 2 2
四个14
三个13

使用
heapq
。这比简单的先计数再排序更复杂,但如果我们需要运行排序计数,这可能会很有用

使用Python的Coffeescript翻译

heap=require./heap'
#改编自
# http://docs.python.org/2/library/heapq.html#priority-队列实现说明
pq=[]#堆中排列的条目列表
entry_finder={}#任务到条目的映射
删除=“”
计数器=[0]
删除任务=(任务)->
#将现有任务标记为已删除。如果未找到,则返回null。
entry=entry\u finder[任务]
如果进入?
删除条目查找器[任务]
条目[entry.length-1]=已删除
返回条目
计数任务=(任务)->
条目=删除任务(任务)
如果进入?
[优先级、计数、计数]=条目
优先级+=1
其他的
计数器[0]+=1
计数=计数器[0]
优先级=1
条目=[优先级、计数、任务]
条目查找器[任务]=条目
堆推(pq,条目)
console.log h=['1','2','1','3','4','2','1']
用于h中的任务
计数任务(任务)
console.log条目\u finder
console.log pq
alist=heap.nlargest(pq,10)
对于列表中的x
[优先级、计数、任务]=x
如果是任务!=远离的
console.log任务、优先级、计数
产生

[ 'one', 'two', 'one', 'three', 'four', 'two', 'one' ]
{ three: [ 1, 3, 'three' ],
  four: [ 1, 4, 'four' ],
  two: [ 2, 2, 'two' ],
  one: [ 3, 1, 'one' ] }

[ [ 1, 1, '<removed-task>' ],
  [ 1, 2, '<removed-task>' ],
  [ 2, 1, '<removed-task>' ],
  [ 1, 3, 'three' ],
  [ 1, 4, 'four' ],
  [ 2, 2, 'two' ],
  [ 3, 1, 'one' ] ]

one 3 1
two 2 2
four 1 4
three 1 3
[‘一’、‘二’、‘一’、‘三’、‘四’、‘二’、‘一’]
{three:[1,3,'three'],
四:[1,4,'四'],
二:[2,2,'二'],
一:[3,1,'1']}
[ [ 1, 1, '' ],
[ 1, 2, '' ],
[ 2, 1, '' ],
[1,3,'三'],
[1,4,4'],
[2,2,'2'],
[3,1,'1']]
1 3 1
2 2 2
四个14
三个13

如果您对标签数组感到满意,那么您可以使用
array:sort
方法:
Object.key(tags).sort(a,b)->tags[a]
。我需要标签名称及其频率,以便在前端显示。也许我可以使用您的排序列表作为中介来重建
标记
对象?是的,您可以。请参阅我的答案了解详细信息。有一些数据结构,通常以树的形式实现,它们在添加项目时保持排序顺序(e