在Ruby和/或Haskell中如何写这个Clojure片段?

前端之家收集整理的这篇文章主要介绍了在Ruby和/或Haskell中如何写这个Clojure片段?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在研究一个Rails模板,并试图写一些代码,允许我填充一个表或多列ul标签“从上到下”和“从左到右”,但是我指定的许多列.我只是得到了 Ruby的悬念,所以我无法想出这一点.我也很好奇这个有用的代码段的惯用Haskell版本. Clojure版本的改进赞赏:
(defn table [xs & {:keys [cols direction]
                   :or   {cols 1 direction 'right}}]
  (into []
        (condp = direction
          'down (let [c (count xs)
                      q (int (/ c cols))
                      n (if (> (mod c q) 0) (inc q) q)]
                  (apply map vector (partition n n (repeat nil) xs)))
          'right (map vec (partition cols cols (repeat nil) xs)))))

使用这一段代码,我可以执行以下操作:

(table (range 10) :cols 3)

打印出来会像这样:

0    1    2 
3    4    5 
6    7    8
9

和更棘手的一个:

(table (range 10) :cols 3 :direction 'down)

看起来像这样:

0    4    8    
1    5    9    
2    6        
3    7

解决方法

我可能会在Haskell中使用来自Hackage的Data.List.Split包写这样的东西:
import Data.List       (intercalate,transpose)
import Data.List.Split (splitEvery)

data Direction = Horizontal | Vertical deriving (Eq,Read,Show)

table :: Direction -> Int -> [a] -> [[a]]
table Horizontal cols xs = splitEvery cols xs
table Vertical   cols xs = let (q,r) = length xs `divMod` cols
                               q'    = if r == 0 then q else q+1
                           in transpose $table Horizontal q' xs

showTable :: Show a => [[a]] -> String
showTable = intercalate "\n" . map (intercalate "\t" . map show)

main :: IO ()
main = mapM_ putStrLn [ showTable $table Horizontal 3 [0..9],"---",showTable $table Vertical   3 [0..9] ]

其中一些,像方向类型和转置技巧,源于jkramer的答案.我不会在Haskell中使用这样的关键字参数(它并不是真的有这样的东西,但是可以使用Edward Kmett的回答中的记录来模拟它们),但是我先把这些参数放在第一位,因为它对部分应用程序更有用(defaultTable =表水平1). splitEvery函数只是将列表分成适当大小的列表;其余的代码应该很简单.表函数返回列表列表;要获取字符串,showTable函数插入标签和换行符. (插入函数连接列表列表,将它们与给定的列表分开,它类似于Perl / Python / Ruby的连接,仅用于列表而不是字符串.)

原文链接:https://www.f2er.com/ruby/267075.html

猜你在找的Ruby相关文章