Haskell列表:根据元素在列表中的位置替换元素

Haskell列表:根据元素在列表中的位置替换元素,haskell,Haskell,我是Haskell的新手,我正试图弄清楚如何编写一个函数来实现这一点,在浏览Google几个小时后,我对如何实现这一点感到不知所措 在Haskell中给出了以下两个列表 [(500,False),(400,False),(952,True),(5,False),(42,False)] [0,2,3] 如何将第一个列表在第二个列表给定的每个位置处的布尔值更改为输出为的True值 [(500,True),(400,False),(952,True),(5,True),(42,False)] 我将

我是Haskell的新手,我正试图弄清楚如何编写一个函数来实现这一点,在浏览Google几个小时后,我对如何实现这一点感到不知所措

在Haskell中给出了以下两个列表

[(500,False),(400,False),(952,True),(5,False),(42,False)]
[0,2,3]
如何将第一个列表在第二个列表给定的每个位置处的布尔值更改为输出为的True值

[(500,True),(400,False),(952,True),(5,True),(42,False)]
我将这样做(假设要替换的索引列表已排序)

首先,我们在要替换的索引列表和原始列表旁边添加一个索引列表。 然后我们沿着列表递归,当我们点击下一个要替换的索引时,我们替换布尔值并在所有三个列表的尾部递归。如果这不是指向的索引 替换我们在整个替换索引列表和其他两个列表的尾部递归

setTrue :: [Int] -> [(a, Bool)] -> [(a, Bool)]
setTrue is xs = go is xs [0..] -- "Index" the list with a list starting at 0.
  where
    go [] xs _ = xs  -- If we're out of indexes to replace return remaining list.
    go _ [] _ = []   -- If we run out of list return the empty list.
    go indexes@(i:is) (x:xs) (cur:cs)
      | i == cur = (fst x, True) : go is xs cs  -- At the next index to replace.
      | otherwise = x : go indexes xs cs -- Otherwise, keep the current element.
我将这样做(假设要替换的索引列表已排序)

首先,我们在要替换的索引列表和原始列表旁边添加一个索引列表。 然后我们沿着列表递归,当我们点击下一个要替换的索引时,我们替换布尔值并在所有三个列表的尾部递归。如果这不是指向的索引 替换我们递归整个替换索引列表和其他两个列表的尾部

setTrue :: [Int] -> [(a, Bool)] -> [(a, Bool)]
setTrue is xs = go is xs [0..] -- "Index" the list with a list starting at 0.
  where
    go [] xs _ = xs  -- If we're out of indexes to replace return remaining list.
    go _ [] _ = []   -- If we run out of list return the empty list.
    go indexes@(i:is) (x:xs) (cur:cs)
      | i == cur = (fst x, True) : go is xs cs  -- At the next index to replace.
      | otherwise = x : go indexes xs cs -- Otherwise, keep the current element.

这基本上与Andrew的方法相同,但它没有使用额外的索引列表,并且受传统的
映射的启发稍微多了一点。请注意,与
map
不同,提供的函数必须是
a->a
,不能是
a->b

restrictedMap :: (a -> a) -> [Int] -> [a] -> [a]
restrictedMap f is xs = go f is xs 0
  where
    go f [] xs _ = xs
    go f _ [] _ = []
    go f ind@(i:is) (x:xs) n
      | i == n    = f x : go f is xs (n+1)
      | otherwise = x : go f ind xs (n+1)

setTrue = restrictedMap (\(x,_) -> (x, True))

这基本上与Andrew的方法相同,但它没有使用额外的索引列表,并且受传统的
映射的启发稍微多了一点。请注意,与
map
不同,提供的函数必须是
a->a
,不能是
a->b

restrictedMap :: (a -> a) -> [Int] -> [a] -> [a]
restrictedMap f is xs = go f is xs 0
  where
    go f [] xs _ = xs
    go f _ [] _ = []
    go f ind@(i:is) (x:xs) n
      | i == n    = f x : go f is xs (n+1)
      | otherwise = x : go f ind xs (n+1)

setTrue = restrictedMap (\(x,_) -> (x, True))

从描述中直接翻译如下:

setIndexTrue f a = [(x, p || i `elem` f) | (i, (x,p)) <- zip [0..] a]

setIndexTrue f a=[(x,p | | i`elem`f)|(i,(x,p))从描述中直接翻译如下:

setIndexTrue f a = [(x, p || i `elem` f) | (i, (x,p)) <- zip [0..] a]
setIndexTrue f a=[(x,p | i`elem`f)|(i,(x,p))或使用神奇库:

或者使用神奇图书馆:


由于我将使用的方法未列出:

setTrue spots values = let
  pattern n = replicate n False ++ [True] ++ Repeat False
  toSet = foldl1 (zipWith (||)) $ map pattern spots
  in zipWith (\s (v,o) -> (v, o || s)) toSet values

由于我将使用的方法未列出:

setTrue spots values = let
  pattern n = replicate n False ++ [True] ++ Repeat False
  toSet = foldl1 (zipWith (||)) $ map pattern spots
  in zipWith (\s (v,o) -> (v, o || s)) toSet values

从函数的签名开始。你认为它应该是什么?我的第一步是将类似于
[0,2,3]
的东西变成
[True,False,True,True,False,False,…]
然后您可以将其与另一个列表和适当的函数压缩。从函数的签名开始。您认为它应该是什么?我的第一步是将类似
[0,2,3]
的内容转换为
[True,False,True,True,False,False,…]
,然后您可以将其与其他列表和适当的函数压缩在一起。