Powershell - 如何有效地过滤具有另一个数组对象的多个键/字段/列的数组对象?



我正在尝试获取数组对象(具有所有数据和更多行)(数组对象 1)中的项目,该数组对象也存在于不同的数组(数组对象 2)(有一些字段,行更少)

由于许多字段重复,我将如何使用多个字段从数组对象 1 获取数据?

要点:字段中没有单个条目是唯一的,但 4 个字段的组合是

具体来说,如何在几个步骤/代码行中做到这一点,并且没有太多的时间和/或资源消耗(我可以使用循环弄清楚如何做到这一点,但这效率低下)

数组对象 1

Number : 10
Place  : UT
Color  : yellow
Zone   : FAHIVT
Group  : 20

Number : 29
Place  : NY
Color  : white
Zone   : HWOUKK
Group  : 8

Number : 66
Place  : TX
Color  : black
Zone   : KZZGKI
Group  : 2

number : 127
Place  : AL
Color  : white
Zone   : DMXDZR
Group  : 14

数组对象 2

Place : NY
Color : white
Group : 2
Zone  : TVQJPN
Place : PA
Color : blue
Group : 4
Zone  : AAYYSN
Place : NJ
Color : red
Group : 17
Zone  : DXKSVE

我在匹配或过滤后寻求的结果是这样的

筛选的数组对象 1

number : 1730
Place  : NY
Color  : white
Zone   : TVQJPN
Group  : 2

number : 2199
Place  : PA
Color  : blue
Zone   : AAYYSN
Group  : 4

number : 2746
Place  : NJ
Color  : red
Zone   : DXKSVE
Group  : 17

我最终做的是一些"特征工程",并将 4 个作为组合唯一的字段组合成一个字符串,并将其作为属性添加到每个数组对象中。Combo = Place + Color + Zone + Group

number : 1730
Place  : NY
Color  : white
Zone   : TVQJPN
Group  : 2
Combo  : NYwhiteTVQJPN2

假设$wholearray是更大更完整的数组,$partialobject是我们需要过滤的较小数组。

以下是我的当前代码

$wholearray.ForEach({
$thisline = $_ ;
$combo = $thisline.Place + $thisline.Color + $thisline.Zone + $thisline.Group;
$wholearray.Where({$_ -eq $thisline}) | Add-Member -NotePropertyName Combo -NotePropertyValue $combo
}
$partialobject.ForEach({
$thisline = $_ ;
$combo = $thisline.Place + $thisline.Color + $thisline.Zone + $thisline.Group;
$partialobject.Where({$_ -eq $thisline}) | Add-Member -NotePropertyName Combo -NotePropertyValue $combo
}
$filtereddata = $wholearray.Where({$_.Combo -in $($partialobject.Combo)}) 

它以循环中每个实例 0.08 秒的平均处理时间为 0.08 秒 但它仍然很慢。仅几千行/实例就需要 5 分钟。当我必须用 20k 或更多来做到这一点时,这将是一场灾难。一直以来,它都可以在 15 秒内完成,使用 vlookup 在 Excel 中甚至更多行。POSH 或 CLI 应该比 Excel 更快。

如何提高工作效率?

我怎样才能使它更快?

一个Compare-Object就可以完成你的任务。

由于Compare-Object并不以速度而闻名,因此您至少有一种测量时间的替代方案。

$Filtered = Compare-Object -Ref $WholeArray -Diff $PartialArray `
-Property Place,Color,Zone,Group `
-IncludeEqual -ExcludeDifferent -PassThru

若要删除插入的属性SideIndicator可以执行以下操作:

$Data = $Filtered | Select-Object -Property * -ExcludeProperty SideIndicator

也许使用此代码和查找哈希表会为您加快速度:

Combo属性添加到$wholearray对象:

$wholearray | ForEach-Object {
$combo = '{0}{1}{2}{3}' -f $_.Place, $_.Color, $_.Zone, $_.Group
$_ | Add-Member -MemberType NoteProperty -Name Combo -Value $combo
}

对于分部数组中的对象,创建一个哈希表对象:

$lookup = @{}
$partialarray | ForEach-Object {
$combo = '{0}{1}{2}{3}' -f $_.Place, $_.Color, $_.Zone, $_.Group
$lookup[$combo] = $true   # the key is the important thing here, the value doesn't matter
}

然后使用以下方法获取过滤后的数据:

$filtereddata = $wholearray | Where-Object { $lookup.ContainsKey($_.Combo)} 

希望有帮助

相关内容

  • 没有找到相关文章

最新更新