Сравнение двух списков в 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]