Вопрос по haskell – Haskell заменяет элемент в списке

16

Есть ли встроенная функция для замены элемента по заданному индексу в haskell?

Пример:

replaceAtIndex(2,"foo",["bar","bar","bar"])

Должен дать:

["bar", "bar", "foo"]

Я знаю, что могу сделать свою собственную функцию, но кажется, что она должна быть встроенной.

Ваш Ответ

3   ответа
11

он не существует по умолчанию. Тем не менее, существуетsplitAt вData.List так:

replaceAtIndex n item ls = a ++ (item:b) where (a, (_:b)) = splitAt n ls

Это O (N), хотя. Если вы обнаружите, что делаете это много, посмотрите на другой тип данных, такой как массив.

Это неO(n) в общем ноO(i), гдеi является индексом разделения (потому что только префикс должен быть скопирован). Если этот индекс постоянен, операцияO(1).
Всегда хорошая идея включить сигнатуру типа:replaceAtIndex :: Int -> a -> [a] -> [a]
32

списки не являются наиболее эффективной структурой данных для этого. Вы можете рассмотреть возможность использованияSeq отData.Sequence вместо этого, в этом случае функция, которую вы ищете,update :: Int -> a -> Seq a -> Seq a.

> import Data.Sequence
> update 2 "foo" $ fromList ["bar", "bar", "bar"]
fromList ["bar","bar","foo"]
@ MickaelBergeronN & # xE9; Рон, мы также получаем[a] снаружиSeq a сData.Foldable.foldMap (:[]) (или с другими моноидами, например,Data.Foldable.foldMap Sum для номеров и т. д.).
Кажется, это именно то, что мне нужно. Спасибо! Stefan Bucur
Я сделал это. Теперь, как мне изменить Seq a на a?
@ MickaelBergeronN & # xE9; Рон, вы можете получить[a] снаружиSeq a сData.Foldable.foldr (:) [], Если у вас естьf :: a -> a -> a операция, вы можете позвонитьData.Foldable.foldr f с некоторым начальным элементом (например, 0), чтобы получить объединенныйa значение.
10

но списки - это действительно односвязные списки, и понятие замены элемента не столь очевидно (и доступ к элементу с заданным индексом может указывать на то, что вы не должны использовать список, поэтому операции, которые могут стимулировать этого избегают).

Похожие вопросы