我有两个列表,其中包含元素ListA([String])和样本位置ListB([Int])如何使用 list comprehensions 创建新的ListC([String])?
例如:
左边的数字总是更右边(参见ListB)
Project.joins(:user_associations)
.where(Project.arel_table[:owner_id].eq(id).or(
ProjectUser.arel_table[:user_id].eq(id)))
更多模板:
Step 1: get elem 1, add the head of the ListC
ListC = ["a"]
Step 2: get elem 2, add the head of the ListC
ListC = ["c","a"]
Step 3: get elem 1, add the head of the ListC
ListC = ["b","c","a"]
so the full chain:
a b c -> 1 2 1 -> a -> c a -> b c a
这个函数是生成有效的数字序列(注意每个左边的元素,它比前一个元素多,至少每1个,即头部是最大的元素)
ListA::[String]
ListB::[int]
ListC::[String]
ListA ListB ListC
a b c -> 3 2 1 -> a b c
a b c -> 2 2 1 -> a c b
a b c -> 3 1 1 -> b a c
a b c -> 1 2 1 -> b c a
a b c -> 2 1 1 -> c a b
a b c -> 1 1 1 -> c b a
答案 0 :(得分:1)
您选择了一种复杂的方式来创建排列,但也许这就是问题域所要求的。
列表推导不能创建所需的排列,但可以用一些简单的实用函数编写
首先写一个drop element函数
dropAt :: Int -> [a] -> [a]
dropAt _ [] = []
dropAt n x = let (h,t) = splitAt n x in (init h) ++ t
现在使用您自己的拣货功能
pickAt :: [Int] -> [a] -> [a]
pickAt _ [] = []
pickAt [] _ = []
pickAt (n:ns) xs = xs!!(n-1) : pickAt ns (dropAt n xs)
给出了相反的顺序,通过反向
> reverse $ pickAt [2,1,1] ['a','b','c']
"cab"
> reverse $ pickAt [1,1,1] ['a','b','c']
"cba"