等同于 Format-Table

huangapple go评论51阅读模式
英文:

Equivalent of Format-Table

问题

Format-Table in PowerShell

在PowerShell中,如果我有一个对象列表:

$items = @(
    [pscustomobject]@{ a = 10;   b = 20;    c = "bcd" }
    [pscustomobject]@{ a = 300;  b = 400;   c = "bcde" }
    [pscustomobject]@{ a = 5000; b = 60000; c = "bcdef" }
)

我可以将这些对象显示为表格:

$items | Format-Table

结果:

   a     b c
   -     - -
  10    20 bcd
 300   400 bcde
5000 60000 bcdef

F#

如果我在F#中有一个类似的列表:

type Abc = {
    a : int
    b : int
    c : string
}

let items = [
    { a = 10; b = 20; c = "bcd" }
    { a = 300; b = 400; c = "bcde" }
    { a = 5000; b = 60000; c = "bcdef" }
]

如果我想要显示类似的表格,我需要更明确:

items |> List.iter (fun item -> printfn "%10d %10d %s" item.a item.b item.c)

format_table 函数

这里有一个 format_table 函数(使用 Fli):

let format_table seq =
    let json = JsonSerializer.Serialize seq
    System.IO.File.WriteAllText("c:/temp/out.json", json)
    let result_cli = (cli {
        Shell PS
        Command "Get-Content c:\\temp\\out.json | ConvertFrom-Json | Format-Table"
    } |> Command.execute)

    match result_cli.Text with
    | Some(txt) -> printfn "%s" txt
    | None -> printfn "issue"

所以我可以这样做:

items |> format_table

然后得到:

   a     b c
   -     - -
  10    20 bcd
 300   400 bcde
5000 60000 bcdef

问题

正如你所看到的,format_table 是一个相当繁琐的解决方案:

  • 它将列表序列化为JSON
  • 它将JSON写入临时文件
  • 它执行PowerShell,使用 Format-Table 处理数据

是否有一种直接的方法来编写类似于 format_table 的东西,而不依赖于外部的PowerShell进程?

英文:

Format-Table in PowerShell

In PowerShell, if I have a list of objects:

$items = @(
    [pscustomobject]@{ a = 10;   b = 20;    c = "bcd" }
    [pscustomobject]@{ a = 300;  b = 400;   c = "bcde" }
    [pscustomobject]@{ a = 5000; b = 60000; c = "bcdef" }
) 

I can display the objects as a table:

$items | Format-Table

The result:

   a     b c
   -     - -
  10    20 bcd
 300   400 bcde
5000 60000 bcdef

F#

If I have a similar list in F#:

type Abc = {
    a : int
    b : int
    c : string
}

let items = [
    { a = 10; b = 20; c = "bcd" }
    { a = 300; b = 400; c = "bcde" }
    { a = 5000; b = 60000; c = "bcdef" }
] 

I have to be more explicit if I want to display a similar table:

items |> List.iter (fun item -> printfn "%10d %10d %s" item.a item.b item.c) 

format_table function

Here's a format_table function (which uses Fli):

let format_table seq =
    let json = JsonSerializer.Serialize seq
    System.IO.File.WriteAllText("c:/temp/out.json", json)
    let result_cli = (cli {
        Shell PS
        Command "Get-Content c:\\temp\\out.json | ConvertFrom-Json | Format-Table"
    } |> Command.execute)

    match result_cli.Text with
    | Some(txt) -> printfn "%s" txt
    | None -> printfn "issue"

So I can do:

items |> format_table

and get:

   a     b c
   -     - -
  10    20 bcd
 300   400 bcde
5000 60000 bcdef

Question

As you can see, format_table is quite the workaround:

  • It serializes the list to JSON
  • It writes the JSON to a temporary file
  • It executes PowerShell which uses Format-Table on the data

Is there a straightforward way to write something similar to format_table without depending on an external PowerShell process?

答案1

得分: 1

这是一个简单版本,使用反射。

open System.Reflection
open FSharp.Reflection

let printTable items =
    let genArgs = items.GetType().GenericTypeArguments
    assert (genArgs.Length = 1)
    let itemType = genArgs[0]
    assert (FSharpType.IsRecord itemType)
    let fieldNames = FSharpType.GetRecordFields itemType |> Array.map (fun propInfo -> propInfo.Name)
    printfn $"""{fieldNames |> Array.map (sprintf "%10s") |> String.concat ""}"""
    printfn $""" {Array.replicate fieldNames.Length "_________ |> String.concat " "}"""
    let printFields item =
        let fields =  FSharpValue.GetRecordFields item
        printfn $"""{fields |> Array.map (string >> sprintf "%10s") |> String.concat ""}"""
    items |> Seq.iter printFields
英文:

Here is a simple version, using reflection.

open System.Reflection
open FSharp.Reflection

let printTable items =
    let genArgs = items.GetType().GenericTypeArguments
    assert (genArgs.Length = 1)
    let itemType = genArgs[0]
    assert (FSharpType.IsRecord itemType)
    let fieldNames = FSharpType.GetRecordFields itemType |> Array.map (fun propInfo -> propInfo.Name)
    printfn $"""{fieldNames |> Array.map (sprintf "%10s") |> String.concat ""}"""
    printfn $""" {Array.replicate fieldNames.Length "_________" |> String.concat " "}"""
    let printFields item =
        let fields =  FSharpValue.GetRecordFields item
        printfn $"""{fields |> Array.map (string >> sprintf "%10s") |> String.concat ""}"""
    items |> Seq.iter printFields

huangapple
  • 本文由 发表于 2023年5月28日 19:22:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/76351234.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定