如何根据haskell中另一个向量的排序顺序重新排序矢量值?

时间:2016-06-07 14:30:54

标签: sorting haskell vector

假设我有两个向量:

  let x = V.fromList ["foo", "bar", "baz"]
  let y = V.fromList [1,3,2]

我想定义一个向量y',它是y的排序版本,但我还想定义一个重新排序的x',它根据{{的排序顺序排序1}}(y应该看起来像x')。

最好的功能是什么?理想情况下,我想避免从头开始编写排序函数。

3 个答案:

答案 0 :(得分:5)

我认为您正在寻找backpermute

backpermute :: Vector a -> Vector Int -> Vector a
     

O(n)通过用i替换索引向量的每个元素xs!i而获得的向量。这相当于map (xs!),但通常效率更高。

答案 1 :(得分:2)

这是一种基于列表的方式:

[(1,"foo"),(3,"bar"),(2,"baz")]

基本上,我们这样拉链以获得对的列表

val doc: org.mongodb.scala.bson.collection.immutable.Document = Document("name" -> "MongoDB", "type" -> "database",
                             "count" -> 1, "info" -> Document("x" -> 203, "y" -> 102))

collection.insertOne(doc)...

然后我们按字典顺序排序,以便第一个组件更重要。

最后,我们丢弃了第一个组件。

你也应该能够适应矢量。

答案 2 :(得分:1)

indices 的向量进行排序,比较索引值;然后permute两个矢量基于排序的索引。 Data.Vector.Algorithms.Intro提供 introsort用于可变向量,modify使用ST Monad提供安全的破坏性更新。

import Data.Ord (comparing)
import Data.Vector.Algorithms.Intro (sortBy)
import Data.Vector.Unboxed (generate, modify)
import Data.Vector (Vector, unsafeIndex, backpermute, convert, fromList)
import qualified Data.Vector as V

reorder :: (Ord b) => Vector a -> Vector b -> (Vector a, Vector b)
reorder a b = (backpermute a idx, backpermute b idx)
    where
    idx  = convert $ modify (sortBy comp) init
    comp = comparing $ unsafeIndex b  -- comparing function
    init = generate (V.length b) id   -- [0..size - 1]

然后,

\> reorder (fromList ["foo", "bar", "baz"]) $ fromList [1, 3, 2]
(["foo","baz","bar"],[1,2,3])