在Ruby和/或Haskell中如何写这个Clojure片段?
发布时间:2020-12-16 21:40:10 所属栏目:百科 来源:网络整理
导读:我正在研究一个Rails模板,并试图写一些代码,允许我填充一个表或多列ul标签“从上到下”和“从左到右”,但是我指定的许多列.我只是得到了 Ruby的悬念,所以我无法想出这一点.我也很好奇这个有用的代码段的惯用Haskell版本. Clojure版本的改进赞赏: (defn tabl
我正在研究一个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的连接,仅用于列表而不是字符串.) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |