在Clojure中,根据元素的长度和频率对此列表中的元素进行排序

在Clojure中,根据元素的长度和频率对此列表中的元素进行排序,clojure,Clojure,今天在一个研讨会上,我们讨论了上面的函数,如果给定,(lfsort'((ab c)(de)(f g h)(de)(i j k l)(mn)(o))输出: (defn lfsort [list](mapcat #(if (sequential? %) % [%]) (sort-by count (vals (group-by count list))))) 我们开始编写一个函数,使用 ((i j k l) (o) (a b c)

今天在一个研讨会上,我们讨论了上面的函数,如果给定,
(lfsort'((ab c)(de)(f g h)(de)(i j k l)(mn)(o))
输出:

(defn lfsort [list](mapcat  #(if (sequential? %) % [%]) 
                              (sort-by count (vals (group-by count list)))))
我们开始编写一个函数,使用

((i j k l)
 (o)
 (a b c)
 (f g h)
 (d e)
 (d e)
 (m n))
输出:

(defn sort [list] (sort-by count list))
我知道sort函数是如何工作的,但我仍然不确定lfsort是如何工作的,有人能帮我把它简化一下吗


谢谢大家!

在REPL中强调交互式编程的语言的优点在于,您可以非常轻松地对构成函数的所有小部分进行实验

首先定义
列表
作为您的数据

((o)
 (d e)
 (d e)
 (m n)
 (a b c)
 (f g h)
 (i j k l))
然后计算
lfsort
函数中的表单(唯一方便命名为
list
的参数)。从计算最里面的表单开始,然后逐渐展开,直到计算完整个函数体。在所有内置函数上使用
doc
,然后进行实验

因此:

…现在我们有了一个计数到大小为“count”的列表的映射

(group-by count list)
; => {3 [(a b c) (f g h)], 2 [(d e) (d e) (m n)], 4 [(i j k l)], 1 [(o)]}
…现在我们有了一个只包含映射值的序列(每个值向量包含大小相等的列表)

…现在,序列中的向量按列表的数量排序

(sort-by count (vals (group-by count list)))
; => ([(i j k l)] [(o)] [(a b c) (f g h)] [(d e) (d e) (m n)])
…最后,列表从向量中解压并展平为一个简单的序列。seq中的列表现在已排序,其大小最不频繁出现在前面的列表


最后一个
mapcat
操作可以用
(apply concat,,,,,,,,,,,
)更简单地表达。

一种在REPL强调交互式编程的语言的优点是,您可以非常轻松地试验构成函数的所有小部分

首先定义
列表
作为您的数据

((o)
 (d e)
 (d e)
 (m n)
 (a b c)
 (f g h)
 (i j k l))
然后计算
lfsort
函数中的表单(唯一方便命名为
list
的参数)。从计算最里面的表单开始,然后逐渐展开,直到计算完整个函数体。在所有内置函数上使用
doc
,然后进行实验

因此:

…现在我们有了一个计数到大小为“count”的列表的映射

(group-by count list)
; => {3 [(a b c) (f g h)], 2 [(d e) (d e) (m n)], 4 [(i j k l)], 1 [(o)]}
…现在我们有了一个只包含映射值的序列(每个值向量包含大小相等的列表)

…现在,序列中的向量按列表的数量排序

(sort-by count (vals (group-by count list)))
; => ([(i j k l)] [(o)] [(a b c) (f g h)] [(d e) (d e) (m n)])
…最后,列表从向量中解压并展平为一个简单的序列。seq中的列表现在已排序,其大小最不频繁出现在前面的列表


最后一个
mapcat
操作可以用
(apply concat,,,,,,,,,,,
更简单地表示。

首先,我们可以简化为

(mapcat #(if (sequential? %) % [%])
  (sort-by count (vals (group-by count list))))
;; => ((i j k l) (o) (a b c) (f g h) (d e) (d e) (m n))
。。。因为
sequential?
总是返回
true

我们可以将其重新表述为

(defn lfsort [coll]
  (apply concat 
   (sort-by count (vals (group-by count coll)))))
。。。使用
->
线程最后一个宏

所以这个函数

  • 获取其参数
    coll
  • 按计数对其集合元素进行分组
  • 丢弃键,映射到向量值
  • 按长度对这些向量进行排序,最后
  • 连接向量

    • 首先,我们可以简化为

      (mapcat #(if (sequential? %) % [%])
        (sort-by count (vals (group-by count list))))
      ;; => ((i j k l) (o) (a b c) (f g h) (d e) (d e) (m n))
      
      。。。因为
      sequential?
      总是返回
      true

      我们可以将其重新表述为

      (defn lfsort [coll]
        (apply concat 
         (sort-by count (vals (group-by count coll)))))
      
      。。。使用
      ->
      线程最后一个宏

      所以这个函数

      • 获取其参数
        coll
      • 按计数对其集合元素进行分组
      • 丢弃键,映射到向量值
      • 按长度对这些向量进行排序,最后
      • 连接向量