简体   繁体   English

组内过滤-组对象

[英]Filtering within a Group - Group-Object

Background info: 背景信息:
Each Element has an IndicatorType of either '10' or 'ND' 每个元素的指标类型为“ 10”或“ ND”
Indicator has values of either '!' 指标的值为“!” , '' (empty string/null), 'o', 'u' ,''(空字符串/空),'o','u'

Question: 题:
I need to filter data in each "Element" group based on this pseudo code rule and then export the result to file: 我需要根据此伪代码规则过滤每个“元素”组中的数据,然后将结果导出到文件中:
For Each "Element" Group if Indicator='!' 对于每个“元素”组,如果指标='!' or '' for BOTH IndicatorTypes(ie '10','ND'), Select group where indicatorType=ND 或``对于BOTH IndicatorTypes(即'10','ND')两者,选择indicatorType = ND的组
ELSE if Indicator='!' 如果指标='! or '' for IndicatorType = 10 and Indicator='o' or 'u' for IndicatorType=ND Select group where indicatorType=10 或对于IndicatorType = 10则为'',对于IndicatorType = ND则为Indicator ='o'或'u'

My Source file: 我的源文件:

"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"

My code grouping by Element : 我的代码按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

PROBEM: 问题:
The problem is with my Where-Object, it returns all the values. 问题出在我的Where-Object上,它返回所有值。
How can I apply the pseudo code rule to my Where-Object to only select the desired group? 如何将伪代码规则应用于我的Where-Object以仅选择所需的组? 在此处输入图片说明

$_.Group will return both objects for the same element, so your tests will filter the list (ex. IndicatorType for both objects in the group) using the value on the right side of -eq , and the condition will most likely be true. $_.Group将返回同一元素的两个对象,因此您的测试将使用-eq右侧的值过滤列表(例如组中两个对象的IndicatorType),并且条件很可能为true 。 Ex: 例如:

$_.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

You solve this by finding the objects in the group you want to perform the tests on first. 您可以通过在要首先执行测试的组中找到对象来解决此问题。

Also, using Group-Object Element | Where-Object … 另外,使用Group-Object Element | Where-Object … Group-Object Element | Where-Object … means that if the where-clause is true, you will keep the whole object returned from Group-Object (containing Count, Name and the elements-group). Group-Object Element | Where-Object …表示如果where子句为true,则将保留从Group-Object返回的整个对象(包含Count,Name和elements-group)。 You should use Foreach-Object instead since you only want to keep one object per approved element-group. 您应该改用Foreach-Object因为您只想为每个批准的元素组保留一个对象。 Try: 尝试:

$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 returns a collection of GroupInfo objects each of which contains a collection of the elements in the group - essentially a list of lists. Group-Object返回GroupInfo对象的集合, GroupInfo对象都包含组中元素的集合-本质上是列表列表。 Running the cmdlet produces (based on the example input) a list of 12 groups: 运行cmdlet会(基于示例输入)产生12个组的列表:

PS[1] (191) > $data = import-csv  data2.txt | group-object element
PS[1] (192) > $data.Count
12

Looking at the first item returned: 查看返回的第一项:

PS[1] > $data[0].Group.Count
2

You can see that it contains two entries which look like: 您可以看到它包含两个看起来像的条目:

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

This means that your selection criteria will have to be applied to each/all of the entries in the collection of data associated with the group to decide if you want to return that group. 这意味着您的选择标准将必须应用于与该组关联的数据集合中的每个/所有条目,以决定是否要返回该组。 In your example code, you appear to be assuming that a group is flat which it's not.Unfortunately I don't entirely understand what you are trying to do so I can't provide a complete answer. 在您的示例代码中,您似乎假设一个组不是一个平面。不幸的是,我不完全了解您要执行的操作,因此无法提供完整的答案。

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

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