2014-09-24 2 views
1

Рассмотрим 2 списка: ["a","b","c"] и ["a","b","c","d","e","f"]Получить X первые элементы из списка

Я хочу, чтобы проверить, если первый список является началом другого списка я думал, что я мог бы использовать:

["a","b","c"] == head (splitAt (length ["a","b","c"]) ["a","b","c","d","e","f"]) 

К сожалению, это не сработает. Есть ли другой способ получить первые 3 элемента из списка в новом списке?

+1

'принимать 3 [" a "," b "," c "," d "," e "," f "]'? Вы должны ознакомиться с Prelude http://hackage.haskell.org/package/base-4.7.0.1/docs/Prelude.html и использовать Hoogle http://www.haskell.org/hoogle/. Например, ваша функция может быть найдена jus, предоставив Hoogle следующие типы: '[a] -> [a]' (т. Е. Вы спросите Hoogle "дать мне функции, которые берут список элементов и возвращают список элементов") http: //www.haskell.org/hoogle/?hoogle=%5Ba%5D+-%3E+%5Ba%5D – seeg

+0

Хорошо, я проверю это. Большое спасибо. –

+0

ваш код будет работать, если вы просто использовали 'fst' вместо' head'. 'fst' берет первый элемент пары,' head' принимает элемент head из непустого списка. –

ответ

6

Вместо того, чтобы использовать take, вы можете использовать zipWith, чтобы избежать перебора списков дважды. Когда вы вызываете length, вам сначала нужно пересечь более короткий список, затем вы берете столько значений из более длинного списка, а затем просматриваете списки, сравнивая элемент за элементом. Что будет более разумным, так это прохождение обоих списков в одно и то же время, прекратив сравнение, когда более короткий срок истек. zipWith обеспечивает именно такую ​​функциональность:

-- Definitions for `and` and `zipWith` in `Prelude` 
-- 
-- and :: [Bool] -> Bool 
-- and [] = True 
-- and (x:xs) = x && and xs 
-- 
-- zipWith :: (a -> b -> c) -> [a] -> [b] -> [c] 
-- zipWith f (x:xs) (y:ys) = f x y : zipWith f xs ys 
-- zipWith _ _  _  = [] 

sameStartingElements :: Eq a => [a] -> [a] -> Bool 
sameStartingElements xs ys = and $ zipWith (==) xs ys 

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

1

Функция, которую вы ищете, это take. См. here.

+2

Хотя это может ответить на вопрос, вы можете улучшить свой ответ: 1) Добавление ссылки на документацию 2) добавить пример ее использования 3) Указать, где OP может найти наиболее часто используемые функции (например, «Прелюдия» и возможно, упоминать «Data.List»). 4) Как он может искать существующие функции (например, Hoogle). – Bakuriu

+0

Отлично, я получил его сейчас. Большое спасибо за быстрый ответ. –

3

Я хочу проверить, является ли первый список началом другого списка.

Вы можете использовать isPrefixOf из модуля Data.List.

Смежные вопросы