2017-12-16 17 views
-2

私は2次元行列に変換したい整数のベクトルを持っています。入力は行サイズで割り切れることが保証されています。ハスケルでこれを行うための最も慣用的な方法は何ですか?ベクトルを2D行列に変換するためのイデオマティックHaskell?

Pythonでは、私はこれを行うだろう:

# Taken from itertools docs. 
def grouper(iterable, n, fillvalue=None): 
    "Collect data into fixed-length chunks or blocks" 
    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx 
    args = [iter(iterable)] * n 
    return itertools.izip_longest(fillvalue=fillvalue, *args) 

m = list(grouper(v, n)) 
+0

'Data.Vector'の' Vector'を意味していますか?あなたの試行を見せてもらえますか? –

+2

['chunksOf :: Int - > [e] - > [[e]]'](https://hackage.haskell.org/package/split-0.2.3.2/docs/Data-List-Split.html# v:chunksOf)。 –

答えて

1

あなたはリストのリストとして表現「マトリックス」にHaskellのリストとして表さ「ベクター」を回す意味と仮定すると、慣用的な解決策がするそうです恥ずかしいエンドレスループを回避するためにガードとおそらく

chunksOf :: Int -> [a] -> [[a]] 
chunksOf _ [] = [] 
chunksOf n xs = 
    let (row, rest) = splitAt n xs 
    in row : chunksOf n rest 

:簡単なパターンマッチングと再帰を使用して行EITHERのリストを構築し、各行を断つためにsplitAtを使用

chunksOf :: Int -> [a] -> [[a]] 
chunksOf n | n > 0 = chunks 
    where 
    chunks [] = [] 
    chunks xs = 
     let (row, rest) = splitAt n xs 
     in row : chunks rest 

OR ELSEunfoldrを使用して:

import Data.List 
chunksOf :: Int -> [a] -> [[a]] 
chunksOf n | n > 0 = unfoldr chunk 
    where 
    chunk [] = Nothing 
    chunk xs = Just (splitAt n xs) 

長さが行の長さの倍数でない場合、最終行が残りの部分よりも短くなります。最終的に不完全な行の塗りつぶし文字を許可するには、次のように記述があります

import Data.List 
chunksOfWithFill :: Int -> a -> [a] -> [[a]] 
chunksOfWithFill n filler | n > 0 = unfoldr chunk 
    where 
    chunk xs = case splitAt n xs of 
     ([],[]) -> Nothing 
     (xs,[]) -> Just (fill xs, []) 
     result -> Just result 
    fill xs = take n (xs ++ repeat filler) 

@Willネスがコメントで指摘するとおり、chunksOfsplitパッケージのData.List.Splitモジュールですでに利用可能です。

関連する問題