假设我有两个向量:
let x = V.fromList ["foo", "bar", "baz"]
let y = V.fromList [1,3,2]
我想定义一个向量y'
,它是y
的排序版本,但我还想定义一个重新排序的x'
,它根据{{的排序顺序排序1}}(y
应该看起来像x'
)。
最好的功能是什么?理想情况下,我想避免从头开始编写排序函数。
答案 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])