list - Haskell <<循环>>

标签 list sorting loops haskell indexing

使用 getIndex xs y 我想要 xs 中长度大于 y 的第一个子列表的索引。

输出是:

[[],[4],[4,3],[3,5,3],[3,5,5,6,1]]
aufgabe6: <<loop>>

为什么 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)

最佳答案

让它终止

问题就在这种情况下

getIndex (x:xs) y
    | length x <= y = 1 + getIndex xs y
    | otherwise = 0
    where (x:xs) = sortList (x:xs)

您混淆了哪个 (x:xs) 是哪个。你应该这样做

getIndex zs y
    | length x <= y = 1 + getIndex xs y
    | otherwise = 0
    where (x:xs) = sortList zs

给予

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

这为您提供了排序列表中长度至少为 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,[])]

让我们创建一个实用函数来处理这些:

hasLength likeThis (_,xs) = likeThis (length xs)

我们可以这样使用它:

*Main> hasLength (==4) (1,[1,2,3,4])
True
*Main> filter (hasLength (>=2)) (zip [1..] ["","yo","hi there","?"])
[(2,"yo"),(3,"hi there")]

这意味着现在可以很容易地编写一个函数来为您提供长度大于 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

这给了我们

*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

更短?

但我们可以做类似的技巧:

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

所以你得到

*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

广义的

让我们把那里的共同主题拉出来:

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

所以我们可以做

*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

关于list - Haskell <<循环>>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16640928/

相关文章:

c# - 如何在 List<T> 中找到未定义字符串的索引

java - 如何在java中对另一个 map 中的一组 map 进行排序?

python - 我如何按组排序?

c - 如何为二维数组分配和释放堆内存?

r - 在列表中查找连续数字组

arrays - 如何在golang中使用for循环将值存储在结构中

c# - 列表始终不包含数组,即使是

python - 如何在 Python 中使用自定义谓词排序

php - 比较数组并在相同顺序下压缩它

python加载几个matlab文件