XHo*_*erX 2 sorting indexing haskell loops list
随着getIndex xs y
我希望第一个子表的索引,xs
其长度大于y
.
输出是:
[[],[4],[4,3],[3,5,3],[3,5,5,6,1]]
aufgabe6: <<loop>>
Run Code Online (Sandbox Code Playgroud)
为什么getIndex
不起作用?
import Data.List
-- Die Sortierfunktion --
myCompare a b
| length a < length b = LT
| otherwise = GT
sortList :: [[a]] -> [[a]]
sortList x = sortBy myCompare x
-- Die Indexfunktion --
getIndex :: [[a]] -> Int -> Int
getIndex [] y = 0
getIndex (x:xs) y
| length x <= y = 1 + getIndex xs y
| otherwise = 0
where (x:xs) = sortList (x:xs)
main = do
print (sortList [[4],[3,5,3],[4,3],[3,5,5,6,1],[]])
print (getIndex [[4],[3,5,3],[4,3],[3,5,5,6,1],[]] 2)
Run Code Online (Sandbox Code Playgroud)
问题出在这种情况下
getIndex (x:xs) y
| length x <= y = 1 + getIndex xs y
| otherwise = 0
where (x:xs) = sortList (x:xs)
Run Code Online (Sandbox Code Playgroud)
你很困惑哪个(x:xs)
是哪个.你应该这样做
getIndex zs y
| length x <= y = 1 + getIndex xs y
| otherwise = 0
where (x:xs) = sortList zs
Run Code Online (Sandbox Code Playgroud)
给
Main> main
[[],[4],[4,3],[3,5,3],[3,5,5,6,1]]
3
*Main> getIndex [[],[2],[4,5]] 1
2
*Main> getIndex [[],[2],[4,5]] 5
3
Run Code Online (Sandbox Code Playgroud)
这为您提供了至少y
在排序列表中的第一个长度列表的编号,它实际上回答了问题" y
原始中有多少列表的长度最多?"
如果您想要原始列表中的位置,您可以使用zip
以下位置标记条目及其位置:
*Main> zip [1..] [[4],[3,5,3],[4,3],[3,5,5,6,1],[]]
[(1,[4]),(2,[3,5,3]),(3,[4,3]),(4,[3,5,5,6,1]),(5,[])]
Run Code Online (Sandbox Code Playgroud)
让我们做一个实用功能来处理那些:
hasLength likeThis (_,xs) = likeThis (length xs)
Run Code Online (Sandbox Code Playgroud)
我们可以像这样使用它:
*Main> hasLength (==4) (1,[1,2,3,4])
True
*Main> filter (hasLength (>=2)) (zip [1..] ["","yo","hi there","?"])
[(2,"yo"),(3,"hi there")]
Run Code Online (Sandbox Code Playgroud)
这意味着现在可以轻松编写一个函数,该函数为您提供长度超过的第一个列表的索引y
:
whichIsLongerThan xss y =
case filter (hasLength (>y)) (zip [1..] xss) of
[] -> error "nothing long enough" -- change this to 0 or (length xss + 1) if you prefer
(x:xs) -> fst x
Run Code Online (Sandbox Code Playgroud)
这给了我们
*Main> whichIsLongerThan [[4],[3,5,3],[4,3],[3,5,5,6,1],[]] 2
2
*Main> whichIsLongerThan [[4],[3,5,3],[4,3],[3,5,5,6,1],[]] 3
4
*Main> whichIsLongerThan [[4],[3,5,3],[4,3],[3,5,5,6,1],[]] 0
1
Run Code Online (Sandbox Code Playgroud)
但我们可以做类似的技巧:
whichIsShorterThan xss y =
case filter (hasLength (<y)) (zip [1..] xss) of
[] -> error "nothing short enough" -- change this to 0 or (length xss + 1) if you prefer
(x:xs) -> fst x
Run Code Online (Sandbox Code Playgroud)
所以你得到了
*Main> whichIsShorterThan [[4],[3,5,3],[4,3],[3,5,5,6,1],[]] 2
1
*Main> whichIsShorterThan [[4],[3,5,3],[4,3],[3,5,5,6,1],[]] 1
5
*Main> whichIsShorterThan [[4],[3,5,3],[4,3],[3,5,5,6,1],[]] 0
*** Exception: nothing short enough
Run Code Online (Sandbox Code Playgroud)
让我们在那里拉出共同主题:
whichLength :: (Int -> Bool) -> [[a]] -> Int
whichLength likeThis xss =
case filter (hasLength likeThis) (zip [1..] xss) of
[] -> error "nothing found" -- change this to 0 or (length xss + 1) if you prefer
(x:xs) -> fst x
Run Code Online (Sandbox Code Playgroud)
所以我们可以做到
*Main> whichLength (==5) [[4],[3,5,3],[4,3],[3,5,5,6,1],[]]
4
*Main> whichLength (>2) [[4],[3,5,3],[4,3],[3,5,5,6,1],[]]
2
Run Code Online (Sandbox Code Playgroud)