ファイル名を10文字にする関数(重複があっても大丈夫)
30分プログラム、その608。ファイル名を一括して先頭10文字に短くするバッチ - バッチもん研究所 blogやhttp://gauc.no-ip.org/awk-users-jp/blis.cgi/DoukakuAWK_172にインスパイアされて、ファイル名を10文字にする関数を書いてみる。
元のスクリプトでは先頭10文字をとるだけだけど、これだとファイル名を被っちゃうかもしれない。
それは嫌なので、ファイル名が重複したら連番を振るようにした。例えば、["a123456789a","a123456789b","a123456789c"]は先頭10文字が同じなので、["a123456789","a123456789(1)","a123456789(2)"]のように番号を振って重複を回避する。
使い方
*Main> shorten ["a123456789a","a123456789b","a123456789c","z"] ["a123456789","a123456789(1)","a123456789(2)","z"]
ソースコード
import Test.HUnit.Base import Test.HUnit.Text import Data.List import Text.Printf count :: Eq a => a -> [a] -> Int count x xs = length $ filter (==x) xs nodup :: Eq a => (a->[a]->a) -> [a] -> [a] nodup f xs = nodup' [] xs where nodup' _ [] = [] nodup' prev (x:xs) = if x `elem` prev then (f x $ filter (==x) prev):nodup' (x:prev) xs else x:nodup' (x:prev) xs shorten :: [String] -> [String] shorten xs = nodup (\x prev -> printf "%s(%d)" x (count x prev)) $ map (take 10) xs test1 = ["foo","bar"] ~=? shorten ["foo","bar"] test2 = ["a123456789","b123456789"] ~=? shorten ["a123456789_______","b123456789_____"] test3 = ["a123456789","a123456789(1)","a123456789(2)","z"] ~=? shorten ["a123456789a","a123456789b","a123456789c","z"] main = runTestTT $ TestList [test1,test2,test3]