Haskell:将列表中的所有索引更改为某个值

时间:2017-02-27 18:18:02

标签: haskell

如果我从这个列表中获得一个对象列表和一些索引的另一个列表,是否有一种简单的方法可以将索引列表中的索引更改为不同值的列表中的每个对象?

E.g。我希望存在一些函数f,以便

f 0 [4,2,5] [6,5,8,4,3,6,2,7]

会输出

[6,5,0,4,0,0,2,7]

3 个答案:

答案 0 :(得分:2)

这是一个使用import Control.Lens f :: a -> [Int] -> [a] -> [a] f x is = elements (`elem` is) .~ x 的漂亮版本:

base

这是一个高效版本,除了import Data.List f :: a -> [Int] -> [a] -> [a] f x is xs = snd $ mapAccumR go is' (zip xs [1..]) where is' = map head . group . sort $ is go [] (y,_) = ([],y) go (i:is) (y,j) = if i == j then (is,x) else (i:is,y) 之外没有任何依赖关系。基本上,我们首先从索引列表中排序(并删除重复项)。这样,我们就不需要为每次替换扫描整个列表。

<FrameLayout...>
    <Button/>
    <TextView/>
    <ImageView/>
</FrameLayout>

答案 1 :(得分:0)

您可以定义辅助函数来替换单个值,然后使用它来折叠列表。

replaceAll :: a -> [Int] -> [a] -> [a]
replaceAll repVal indices values = foldl (replaceValue repVal) values indices
                            where replaceValue val vals index = (take index vals) ++ [val] ++ (drop (index + 1) vals)

答案 2 :(得分:0)

首先对索引进行排序。然后你可以串联遍历两个列表。

 function run(e) {
   var div = document.createElement("div"); 
   div.setAttribute('class', 'Delete'); 
   div.addEventListener("click", run); 
   e.target.appendChild(div);
   this.removeEventListener("click", run); 
   e.stopPropagation()

}
function removeChildDiv(e)  
{
    if(e.target.className === 'Delete')  
    {
        e.target.parentNode.removeChild(e.target);
    } 
     document.getElementById("1").addEventListener("click", run);
}

 document.getElementById("1").addEventListener("click", run); 
 document.getElementById("1").addEventListener("click", removeChildDiv);

排序会在索引列表的长度上产生额外的 log 因子,但其余因素是线性的。