繁体   English   中英

如何避免 F# Seq.map 中的自动排序

[英]How to avoid auto sorts in F# Seq.map

Seq.map返回一个排序对,但我不需要它。有什么办法可以避免根据键值对 map 进行排序。 我想以相同的顺序显示所有对,我将其插入 map。

根据文档,F# Map.toSeq将返回按键排序的所有 map 条目。 如果您想按照添加的顺序遍历项目,那么Map是不合适的。 您将需要一个不同的数据结构。

一种选择是使用list

let xs =
  []
  |> fun xs -> (1, "a") :: xs
  |> fun xs -> (2, "b") :: xs
  |> fun xs -> (7, "x") :: xs
  |> fun xs -> (3, "c") :: xs

for x in List.rev xs do
  printfn $"%A{x}"

// (1, "a")
// (2, "b")
// (7, "x")
// (3, "c")

请注意,项目是按倒序迭代的,因此需要List.rev才能获得原始顺序。

由于您使用的是Map ,因此您似乎只想为每个键保留一个值。 这可以使用自定义类型来完成。

type OrderPreservingMap<'k, 'v when 'k : comparison> =
  {
    Items : Map<'k, 'v>

    // Track when keys were inserted, with the most recent first
    Insertions : 'k list
  }

module OrderPreservingMap =

  let empty<'k, 'v when 'k : comparison> : OrderPreservingMap<'k, 'v> =
    {
      Items = Map.empty
      Insertions = []
    }

  let add (k : 'k) (v : 'v) (m : OrderPreservingMap<'k, 'v>) =
    if Map.containsKey k m.Items then
      {
        Items = Map.add k v m.Items
        Insertions = k :: (m.Insertions |> List.except [ k ])
      }
    else
      {
        Items = Map.add k v m.Items
        Insertions = k :: m.Insertions
      }

  let toSeq (m : OrderPreservingMap<'k, 'v>) =
    m.Insertions
    |> List.rev
    |> Seq.map
      (fun k -> k, Map.find k m.Items)

用法:

let xs =
  OrderPreservingMap.empty
  |> OrderPreservingMap.add 1 "a"
  |> OrderPreservingMap.add 2 "b"
  |> OrderPreservingMap.add 7 "x"
  |> OrderPreservingMap.add 3 "c"

for x in OrderPreservingMap.toSeq xs do
  printfn $"%A{x}"

// (1, "a")
// (2, "b")
// (7, "x")
// (3, "c")

暂无
暂无

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

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