[英]Filtering within a Group - Group-Object
背景信息:
每個元素的指標類型為“ 10”或“ ND”
指標的值為“!” ,''(空字符串/空),'o','u'
題:
我需要根據此偽代碼規則過濾每個“元素”組中的數據,然后將結果導出到文件中:
對於每個“元素”組,如果指標='!' 或``對於BOTH IndicatorTypes(即'10','ND')兩者,選擇indicatorType = ND的組
如果指標='! 或對於IndicatorType = 10則為'',對於IndicatorType = ND則為Indicator ='o'或'u'
我的源文件:
"Code","IndicatorType","Indicator","Element","Data"
"111","10","","S","0.039"
"111","10","!","Cr ","0.045"
"111","10","","Zn","0.011"
"111","10","!","P","0.013"
"111","10","","Ni ","56.480"
"111","10","!","Co ","1.081"
"111","10","!","Fe","45.655"
"111","10","!","Si","0.364"
"111","10","!","Mn","0.005"
"111","10","!","Al","0.007"
"111","10","!","Cu","0.014"
"111","10","!","Y","0.00"
"111","ND","","S","0.037"
"111","ND","","Cr ","0.039"
"111","ND","","Zn","0.010"
"111","ND","","P","0.013"
"111","ND","o","Ni ","37.107"
"111","ND","o","Co ","0.887"
"111","ND","o","Fe","37.430"
"111","ND","","Si","0.348"
"111","ND","","Mn","0.005"
"111","ND","","Al","0.008"
"111","ND","","Cu","0.013"
"111","ND","","Y","0.00"
我的代碼按Element分組:
$myfile = Get-ChildItem -Path $myfileSource *.csv
$myfileData = Import-Csv $myfile.FullName | Group-Object Element |
Where-Object -FilterScript {($_.Group.IndicatorType -eq 'ND' -and
$_.Group.Indicator -eq '!' -or
$_.Group.Indicator -eq '') -or
($_.Group.IndicatorType -eq '10' -and
$_.Group.Indicator -eq 'o' -or
$_.Group.Indicator -eq 'u' -or
$_.Group.Indicator -eq '!' -or
$_.Group.Indicator -eq '')
}| Export-Csv -Path $myFile.FullName -Force -NoTypeInformation
問題:
問題出在我的Where-Object上,它返回所有值。
如何將偽代碼規則應用於我的Where-Object以僅選擇所需的組?
$_.Group
將返回同一元素的兩個對象,因此您的測試將使用-eq
右側的值過濾列表(例如組中兩個對象的IndicatorType),並且條件很可能為true 。 例如:
$_.Group.IndicatorType -eq 'ND'
#Translates to array of "IndicatorTypes in the group" -eq 'ND'
10,'ND' -eq 'ND'
#The line above filters the array on the left to show matching values, this returns
'ND'
#A value is always true, so this test will be
$true
您可以通過在要首先執行測試的組中找到對象來解決此問題。
另外,使用Group-Object Element | Where-Object …
Group-Object Element | Where-Object …
表示如果where子句為true,則將保留從Group-Object
返回的整個對象(包含Count,Name和elements-group)。 您應該改用Foreach-Object
因為您只想為每個批准的元素組保留一個對象。 嘗試:
$myfile = Get-ChildItem -Path $myfileSource *.csv
$myfileData = Import-Csv $myfile.FullName |
#For Each "Element" Group
Group-Object Element | Foreach-Object {
$Ten = $_.Group | Where-Object { $_.IndicatorType -eq '10' }
$ND = $_.Group | Where-Object { $_.IndicatorType -eq 'ND' }
if(('!','' -contains $Ten.Indicator) -and ('!','' -contains $ND.Indicator)) {
#if Indicator='!' or '' for BOTH IndicatorTypes(ie '10','ND'), Select group where indicatorType=ND
$ND
} elseif (('!','' -contains $Ten.Indicator) -and ('o','u' -contains $ND.Indicator)) {
#ELSE if Indicator='!' or '' for IndicatorType = 10 and Indicator='o' or 'u' for IndicatorType=ND Select group where indicatorType=10
$Ten
}
} | Export-Csv -Path $myFile.FullName -Force -NoTypeInformation
Group-Object
返回GroupInfo
對象的集合, GroupInfo
對象都包含組中元素的集合-本質上是列表列表。 運行cmdlet會(基於示例輸入)產生12個組的列表:
PS[1] (191) > $data = import-csv data2.txt | group-object element
PS[1] (192) > $data.Count
12
查看返回的第一項:
PS[1] > $data[0].Group.Count
2
您可以看到它包含兩個看起來像的條目:
PS[1] (193) > $data[0].Group
Code : 111
IndicatorType : 10
Indicator :
Element : S
Data : 0.039
Code : 111
IndicatorType : ND
Indicator :
Element : S
Data : 0.037
這意味着您的選擇標准將必須應用於與該組關聯的數據集合中的每個/所有條目,以決定是否要返回該組。 在您的示例代碼中,您似乎假設一個組不是一個平面。不幸的是,我不完全了解您要執行的操作,因此無法提供完整的答案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.