gpt4 book ai didi

ruby - 你会如何用 Ruby 和/或 Haskell 编写这个 Clojure 片段?

转载 作者:数据小太阳 更新时间:2023-10-29 06:46:15 25 4
gpt4 key购买 nike

我当时正在研究一个 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

最佳答案

我可能会使用来自 Hackage 的 Data.List.Split 包在 Haskell 中编写类似的东西:

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] ]

其中一些,例如 Direction 类型和 transpose 技巧,源自 jkramer 的回答。我不会在 Haskell 中为这样的东西使用关键字参数(它实际上没有这样的东西,但你可以像 Edward Kmett 的回答中那样使用记录来模拟它们),但我把这些参数放在第一位是因为它对部分应用程序更有用(defaultTable = table Horizo​​ntal 1)。 splitEvery 函数只是将一个列表分成适当大小的列表;其余代码应该很简单。 table 函数返回列表的列表;要获取字符串,showTable 函数会插入制表符和换行符。 (intercalate 函数连接列表的列表,将它们与给定列表分开。它类似于 Perl/Python/Ruby 的 join,仅用于列表而不是字符串。)

关于ruby - 你会如何用 Ruby 和/或 Haskell 编写这个 Clojure 片段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2819652/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com