Сравнение двух списков в Haskell

У меня есть два списка в Хаскеле.

Оригинальный список: ["Привет", "Привет", "Мир", "МИР"]

Только верхний регистр: ["HELLO", "WORLD"]

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

Я могу получить первый индекс, выполнив это:

пусть upperIndex = findIndices(==(onlyUpper!! 0)) оригинал

Тем не менее, это работает только для одного экземпляра, в этом случае я могу получить только индекс "Привет" в исходном списке, но я хочу получить все из них.

Для этого примера ответ должен быть: [1,3]

2 ответа

Решение

Изменить: Другая версия, предложенная Дэвидом Янгом

findIndicesIn xs ys = findIndices (`elem` ys) xs

который я предпочитаю своему решению ниже.


Если я правильно понимаю, у вас есть два списка. Позвони им xs а также ys, Вы хотите найти индекс в xs каждого элемента в ys, Вы не упоминаете, что вы хотите сделать, если элемент в ys не содержится в xsПоэтому я собираюсь выбрать что-то разумное для вас. Вот:

findIndicesIn :: Eq a => [a] -> [a] -> [Maybe Int]
findIndicesIn xs ys = map (`elemIndex` xs) ys

elemIndex :: Eq a => a -> [a] -> Maybe Int находит индекс данного элемента в списке (по сравнению с (==)). Если элемент не существует, Nothing возвращается вместо. Чтобы найти все индексы, мы сопоставляем каждый элемент в ys и попытаться найти его в xs с помощью elemIndex, Синтаксис раздела используется вместо flip elemIndex xs или же \y -> elemIndex y xs для краткости.

Результатом является список Maybe Int представляющие возможные показатели в xs каждого элемента в ys, Обратите внимание, что если вы не отследите отсутствующие элементы, позиции индексов в результирующем списке больше не будут соответствовать позициям элементов в ys,

Вы также можете написать это, используя меньше очков, как

findIndicesIn :: Eq a => [a] -> [a] -> [Maybe Int]
findIndicesIn xs = map (`elemIndex` xs)

YMMV, на котором более ясно. Оба эквивалентны. Эта версия довольно читабельная ИМО. Вы можете пойти еще дальше и написать

findIndicesIn = map . flip elemIndex

но лично я нахожу это менее читабельным. YMMV снова.

let upperIndex original onlyUpper = helper original 0 where helper [] _ = []; helper (x:xs) i = if elem x onlyUpper then i:(helper xs (i+1)) else helper xs (i+1)

Пример использования:

Prelude> upperIndex ["hello", "HELLO", "world", "WORLD"] ["HELLO", "WORLD"]
[1,3]
Другие вопросы по тегам