简体   繁体   English

Haskell列表推导列表A listB-> listC

[英]Haskell List Comprehensions listA listB -> listC

I have two lists with elements ListA ([String]) and sample positions ListB([Int]) how to create a new ListC ([String]) using list comprehensions ? 我有两个包含元素ListA([String])和示例位置ListB([Int])的列表,如何使用列表推导创建新的ListC([String])?

for example: 例如:

the left number is always more right (see ListB) 左边的数字总是更右边(请参阅ListB)

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

more templates: 更多模板:

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

this function is to generate valid numeric sequences (note each left element, it is more than the previous one, at least per 1, ie. head is the greatest element) 此函数用于生成有效的数字序列(请注意,每个左元素,至少比每1个元素都要多于前一个元素,即head是最大的元素)

module Main ( main ) where

import System.Random

main :: IO ()

randomList :: Int -> [Int] -> StdGen -> [Int]
randomList 0 xlist _ = reverse xlist
randomList n xlist gen = randomList (n-1) (randomVal : xlist) gen'
    where (randomVal, gen') = randomR (1,n) gen

shuffle :: [Int] -> [String] -> [String] -> [String]
shuffle [] _ deckB = deckB
shuffle pl deckA deckB = shuffle (tail pl) (hs ++ tail ts) (head ts : deckB)
    where (hs, ts) = splitAt (pos-1) deckA
          pos = head pl

ranks = ["2","3","4","5","6","7","8","9","T","J","Q","K","A"]
suits = ["C","D","H","S"]
deck = [rank ++ suit | suit <- suits, rank <- ranks]

main = do
    gen <- newStdGen
    let len = 52 :: Int
    let permutationList = randomList len [] gen
    let newDeck = shuffle permutationList deck []
    print permutationList
    print deck
    print "-------------------------------------"
    print newDeck

You chose a complicated way to create the permutations but perhaps that's what the problem domain dictates. 您选择了一种复杂的方法来创建排列,但这也许就是问题域所要说明的。

The required permutation cannot be created by list comprehensions but can be written with some simple utility functions 所需的排列不能通过列表理解来创建,但可以使用一些简单的实用程序函数来编写

first write a drop element function 首先编写一个drop元素函数

dropAt :: Int -> [a] -> [a]
dropAt _ [] = []
dropAt n x  = let (h,t) = splitAt n x in (init h) ++ t

now using this your own picking function 现在使用这个您自己的选择功能

pickAt :: [Int] -> [a] -> [a]
pickAt _ [] = []
pickAt [] _ = []
pickAt (n:ns) xs = xs!!(n-1) : pickAt ns (dropAt n xs)

gives you the reverse order though, run through reverse 给你相反的顺序

> reverse $ pickAt [2,1,1] ['a','b','c']
"cab"

> reverse $ pickAt [1,1,1] ['a','b','c']
"cba"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM