В Haskell, выполнение этого для n-мерных списков, как поддерживает эквивалент NumPy, требует довольно продвинутой конструкции класса типов, но одномерный случай прост:
select :: [Bool] -> [a] -> [a] -> [a]
select [] [] [] = []
select (True:bs) (x:xs) (_:ys) = x : select bs xs ys
select (False:bs) (_:xs) (y:ys) = y : select bs xs ys
Это всего лишь простая рекурсивная процедура, по очереди проверяющая каждый элемент каждого списка и создающая пустой список, когда каждый список достигает своего конца. (Обратите внимание, что это списки, а не массивы.)
Вот более простая, но менее очевидная реализация для одномерных списков, переведя определение в документацию NumPy (благодарность Хоакину за указание на это):
select :: [Bool] -> [a] -> [a] -> [a]
select bs xs ys = zipWith3 select' bs xs ys
where select' True x _ = x
select' False _ y = y
Для достижения случая с двумя аргументами (возвращая все индексы, где условие истинно; спасибо Рексу Керру за указание этого случая), можно использовать понимание списка:
trueIndices :: [Bool] -> [Int]
trueIndices bs = [i | (i,True) <- zip [0..] bs]
Это также может быть записано с существующим select
, хотя в этом нет особого смысла:
trueIndices :: [Bool] -> [Int]
trueIndices bs = catMaybes $ select bs (map Just [0..]) (repeat Nothing)
А вот версия с тремя аргументами для n-мерных списков:
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}
class Select bs as where
select :: bs -> as -> as -> as
instance Select Bool a where
select True x _ = x
select False _ y = y
instance (Select bs as) => Select [bs] [as] where
select = zipWith3 select
Вот пример:
GHCi> select [[True, False], [False, True]] [[0,1],[2,3]] [[4,5],[6,7]]
[[0,5],[6,3]]
Вы, вероятно, захотите использовать вместо этого правильный n-мерный тип массива на практике. Если вы просто хотите использовать select
в n-мерном списке для одного конкретного n , совет Луки (из комментариев к этому ответу) предпочтителен:
На практике вместо взлома класса типов я бы использовал (zipWith3.zipWith3.zipWith3) select' bs xs ys
(для трехмерного случая).
(добавление новых композиций zipWith3
по мере увеличения n .)