0

I've a field made of list of lists like this:

let list1 = ["a", "abcdefgh", "abc"]

I want to get a new field 5x5 such that there could be more then 5 lines or columns, but no less. It must be produced from the previous one by addition spaces ' ' or keeping them as they are, if there are more then 5 symbols. For additional lines no spaces needed. For example:

list2 = ["a    ", "abcdefgh", "abc  ", "     ", "     "]

or:

let list1 = ["a", "abcdefgh", "c", "d", "e", "f"]
list2 = ["a    ", "abcdefgh", "c    ", "d    ", "e    ", "f"]

I thought about map, replicate, and length, but I'm a little bit confused. If it's possible, don't use libs (or use Data.Map only). Thank you

5
  • 2
    Exactly what did you try? Commented Apr 3, 2021 at 9:34
  • I made sth. like this: (map (++ (replicate 5 ' ')) linesOfFiles) ++ (replicate (5- length linesOfFiles) (replicate 5' ')) But that's not what I want Commented Apr 3, 2021 at 9:36
  • Your map will each time add five spaces to each line. You should determine the length of the string, and append accordingly... Commented Apr 3, 2021 at 9:37
  • @WillemVanOnsem Yes, I know, but I don't know how I can determine the length of the string inside the map function Commented Apr 3, 2021 at 9:39
  • you work with a lambda expression: map (\x -> ...). Commented Apr 3, 2021 at 9:42

1 Answer 1

1

You need to determine the length of the strings. You can do this for example with a lambda expression, so then the mapping looks like:

func :: [String] -> [String]
func mylines = map (\x -> … ) linesOfFiles ++ replicate (5-length mylines) (replicate 5' ')

where x is thus string that will be mapped, and is an expression to what that value is mapped. I leave filling in as an exercise.

Usually it is better not to work with length: length takes linear time, and for infinite lists, this will even get the program into an infinite loop.

You can work with recursion to perform padding, something like:

padding :: Int -> a -> [a] -> [a]
padding 0 _ xs = …
padding n x [] = …
padding n x (x:xs) = …
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you, I already understood this after your first comment. I'm just trying to do it now
Thanks again, I've not so much pracrice in lambda usage.I know about the linear time, but I get the list form the input file, so it doesn't take so much time. I made: (map (\x -> (x ++ (replicate (5 - (length x)) ' '))) linesOfFiles) ++ (replicate (5- length linesOfFiles) (replicate 5' '))
@TheWorstHaskellProger: Instead of computing the number of spaces, one way to avoid length is to think of the problem as: 1. pad the input with spaces in both directions, then 2. trim it to the desired size with take. Look at the result of take 5 ("abc" ++ repeat ' '), and consider how you could use this pattern in your code. Also, notice how take 5 (x ++ repeat ' ') is different from x ++ replicate (5 - length x) ' ' when length x is greater than 5, as in "abcdefg". Your question and your sample input/output are a little unclear about which of these results you want.
@JonPurdy Sorry, I made a mistake when I wrote "there could be more then 5 lines or columns, but no more" I should have written "no less". So you see, replicate (length (-10)) ' ' will not change my line, but take const will cut my lines. I'll correct the error right now. Thank you for the answer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.