gpt4 book ai didi

json - 将嵌套 JSON 数组转换为 CSV 文件中的单独列

转载 作者:行者123 更新时间:2023-12-02 05:41:13 26 4
gpt4 key购买 nike

我有一个如下所示的 JSON 文件:

{
"id": 10011,
"title": "Test procedure",
"slug": "slug",
"url": "http://test.test",
"email": "test@test.com",
"link": "http://test.er",
"subject": "testing",
"level": 1,
"disciplines": [
"discipline_a",
"discipline_b",
"discipline_c"
],
"areas": [
"area_a",
"area_b"
]
},

我尝试使用以下命令将其转换为 CSV 文件:

(Get-Content "PATH_TO\test.json" -Raw | ConvertFrom-Json)| Convertto-CSV -NoTypeInformation | Set-Content "PATH_TO\test.csv"

但是,对于学科和领域,我在生成的 CSV 文件中获取 System.Object[]。

有没有办法将所有这些嵌套值作为单独的列放入 CSV 文件中,例如area_1、area_2 等。学科也是如此。

最佳答案

2017-11-20,完全重写函数以提高性能并添加功能为-ArrayBase以及对 PSStandardMembers 和分组对象的支持。

展平对象

递归地展平包含数组、哈希表和(自定义)对象的对象。所提供的 objects will be aligned 的所有添加属性与其余对象。

需要 PowerShell 版本 2 或更高版本。

cmdlet

Function Flatten-Object {                                       # Version 00.02.12, by iRon
[CmdletBinding()]Param (
[Parameter(ValueFromPipeLine = $True)][Object[]]$Objects,
[String]$Separator = ".", [ValidateSet("", 0, 1)]$Base = 1, [Int]$Depth = 5, [Int]$Uncut = 1,
[String[]]$ToString = ([String], [DateTime], [TimeSpan]), [String[]]$Path = @()
)
$PipeLine = $Input | ForEach {$_}; If ($PipeLine) {$Objects = $PipeLine}
If (@(Get-PSCallStack)[1].Command -eq $MyInvocation.MyCommand.Name -or @(Get-PSCallStack)[1].Command -eq "<position>") {
$Object = @($Objects)[0]; $Iterate = New-Object System.Collections.Specialized.OrderedDictionary
If ($ToString | Where {$Object -is $_}) {$Object = $Object.ToString()}
ElseIf ($Depth) {$Depth--
If ($Object.GetEnumerator.OverloadDefinitions -match "[\W]IDictionaryEnumerator[\W]") {
$Iterate = $Object
} ElseIf ($Object.GetEnumerator.OverloadDefinitions -match "[\W]IEnumerator[\W]") {
$Object.GetEnumerator() | ForEach -Begin {$i = $Base} {$Iterate.($i) = $_; $i += 1}
} Else {
$Names = If ($Uncut) {$Uncut--} Else {$Object.PSStandardMembers.DefaultDisplayPropertySet.ReferencedPropertyNames}
If (!$Names) {$Names = $Object.PSObject.Properties | Where {$_.IsGettable} | Select -Expand Name}
If ($Names) {$Names | ForEach {$Iterate.$_ = $Object.$_}}
}
}
If (@($Iterate.Keys).Count) {
$Iterate.Keys | ForEach {
Flatten-Object @(,$Iterate.$_) $Separator $Base $Depth $Uncut $ToString ($Path + $_)
}
} Else {$Property.(($Path | Where {$_}) -Join $Separator) = $Object}
} ElseIf ($Objects -ne $Null) {
@($Objects) | ForEach -Begin {$Output = @(); $Names = @()} {
New-Variable -Force -Option AllScope -Name Property -Value (New-Object System.Collections.Specialized.OrderedDictionary)
Flatten-Object @(,$_) $Separator $Base $Depth $Uncut $ToString $Path
$Output += New-Object PSObject -Property $Property
$Names += $Output[-1].PSObject.Properties | Select -Expand Name
}
$Output | Select ([String[]]($Names | Select -Unique))
}
}; Set-Alias Flatten Flatten-Object

语法

<Object[]> Flatten-Object [-Separator <String>] [-Base "" | 0 | 1] [-Depth <Int>] [-Uncut<Int>] [ToString <Type[]>]

或者:

Flatten-Object <Object[]> [[-Separator] <String>] [[-Base] "" | 0 | 1] [[-Depth] <Int>] [[-Uncut] <Int>] [[ToString] <Type[]>]

参数

<强> -Object[] <Object[]>
要压平的对象(或多个对象)。

<强> -Separator <String> (默认: . )
递归属性名称之间使用的分隔符。 .

<强> -Depth <Int> (默认: 5 )
展平递归属性的最大深度。任何负值都将导致无限深度,并可能导致无限循环。

<强> -Uncut <Int> (默认: 1 )
未切割更多对象属性的对象迭代次数将仅限于 DefaultDisplayPropertySet 。任何负值都会显示所有对象的所有属性。

<强> -Base "" | 0 | 1 (默认: 1 )
嵌入数组的第一个索引名称:

  • 1 ,数组将从 1 开始:<Parent>.1 , <Parent>.2 , <Parent>.3 ,...
  • 0 ,数组将从 0 开始:<Parent>.0 , <Parent>.1 , <Parent>.2 ,...
  • "" ,数组中的第一项将是未命名的,并且后面跟着 1: <Parent> , <Parent>.1 , <Parent>.2 ,...

<强> -ToString <Type[]= [String], [DateTime], [TimeSpan]>
将转换为字符串而不是进一步扁平化的值类型列表(默认 [String], [DateTime], [TimeSpan] )。例如。一个[DateTime]可以使用 Date 等附加属性进行扁平化, Day , DayOfWeek等,但会被转换为单个 ( String ) 属性。

注意:
参数-Path 供内部使用,但只能用于前缀属性名称。

示例

回答具体问题:

(Get-Content "PATH_TO\test.json" -Raw | ConvertFrom-Json) | Flatten-Object | Convertto-CSV -NoTypeInformation | Set-Content "PATH_TO\test.csv"

结果:

{
"url": "http://test.test",
"slug": "slug",
"id": 10011,
"link": "http://test.er",
"level": 1,
"areas.2": "area_b",
"areas.1": "area_a",
"disciplines.3": "discipline_c",
"disciplines.2": "discipline_b",
"disciplines.1": "discipline_a",
"subject": "testing",
"title": "Test procedure",
"email": "test@test.com"
}

对更复杂的自定义对象进行压力测试:

New-Object PSObject @{
String = [String]"Text"
Char = [Char]65
Byte = [Byte]66
Int = [Int]67
Long = [Long]68
Null = $Null
Booleans = $False, $True
Decimal = [Decimal]69
Single = [Single]70
Double = [Double]71
Array = @("One", "Two", @("Three", "Four"), "Five")
HashTable = @{city="New York"; currency="Dollar"; postalCode=10021; Etc = @("Three", "Four", "Five")}
Object = New-Object PSObject -Property @{Name = "One"; Value = 1; Text = @("First", "1st")}
} | Flatten

结果:

Double               : 71
Decimal : 69
Long : 68
Array.1 : One
Array.2 : Two
Array.3.1 : Three
Array.3.2 : Four
Array.4 : Five
Object.Name : One
Object.Value : 1
Object.Text.1 : First
Object.Text.2 : 1st
Int : 67
Byte : 66
HashTable.postalCode : 10021
HashTable.currency : Dollar
HashTable.Etc.1 : Three
HashTable.Etc.2 : Four
HashTable.Etc.3 : Five
HashTable.city : New York
Booleans.1 : False
Booleans.2 : True
String : Text
Char : A
Single : 70
Null :

展平分组对象:

$csv | Group Name | Flatten | Format-Table # https://stackoverflow.com/a/47409634/1701026

展平常见对象:

(Get-Process)[0] | Flatten-Object

或者对象列表(数组):

Get-Service | Flatten-Object -Depth 3 | Export-CSV Service.csv

请注意,如下命令需要数小时才能计算:

Get-Process | Flatten-Object | Export-CSV Process.csv

为什么?因为它会生成一个包含数百行和数千列的表。因此,如果您想将其用于展平过程,最好限制行数(使用 Where-Object cmdlet)或列数(使用 Select-Object cmdlet)。

最新Flatten-Object版本,请参阅:https://powersnippets.com/flatten-object/

关于json - 将嵌套 JSON 数组转换为 CSV 文件中的单独列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45829754/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com