首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >哈希表会加速这件事吗?如果是这样的话,我会怎样做呢?

哈希表会加速这件事吗?如果是这样的话,我会怎样做呢?
EN

Stack Overflow用户
提问于 2015-12-22 14:18:47
回答 2查看 73关注 0票数 1

我在寻找两个数组的负交集。每个数组都有大约20k个元素。我在一个数组上使用一个foreach循环,并在另一个数组中查找每个值。我只在第一个数组中保留元素,而在第二个数组中找不到:

代码语言:javascript
复制
$deadpaths=@()
$ix=0
ForEach ($f in $FSBuildIDs)
{
    if (-not($blArray -like $f)) {$deadpaths+=$paths[$ix]}
    $ix++
}

$blArray包含有效的ID。$FSBuildIDs包含与$paths中的文件系统路径对应的ID。其目的是只将元素保留在$paths中,而$FSBuildIDS中的相应ID不在$blArray中。

有更好的方法吗?这里的处理需要非常长的时间。$blArray和$FSBuildIDs都有大约20k的元素,我怀疑我正在研究^2的比较。

我考虑使用一个字典,其中$FSBuildIDs元素作为键,$paths元素作为值,但我无法从文档中找到如何初始化和加载字典(假设这种方法会加快速度)。显然,负集交集最好,但这不是TSQL,我痛苦地意识到,即使是PS的V4也不支持set操作。

在这个问题上使用字典会加快比较速度吗?如果是这样,我如何从$FSBuildIDs和$paths创建它?还有其他技术可以提高我的性能,而不是只在这些大列表(Ish)上迭代?

$blArray的样本数据:

代码语言:javascript
复制
51012
51044
51049
51055
51058
51060
51073
51074
51077
51085

$FSBuildIDs的样本数据:

代码语言:javascript
复制
51001
51003
51005
51009
51013
51017
51018
51020
51021
51024
51026

$paths的样本数据:

代码语言:javascript
复制
\\server1\d$\software\anthill\var\artifacts\0000\3774\0000\3792\0005\2335
\\server1\d$\software\anthill\var\artifacts\0000\3774\0000\3792\0005\2336
\\server1\d$\software\anthill\var\artifacts\0000\3774\0000\3792\0005\2337
\\server1\d$\software\anthill\var\artifacts\0000\3774\0000\3792\0005\2338
\\server1\d$\software\anthill\var\artifacts\0000\3774\0000\3792\0005\2339
\\server1\d$\software\anthill\var\artifacts\0000\3774\0000\3792\0005\2340
\\server1\d$\software\anthill\var\artifacts\0000\3774\0000\3792\0005\2341

这与先前提出的问题相似,但在某些方面有所不同。实际上,我正在寻找从两个现有数组构建字典的指南。在发帖后,我意识到我确实需要一个来自$blarray的字典作为键,可能需要$True作为值。价值是无关紧要的。重要的测试是$FSBuildIDs中的当前值是否在$blarray中找到。这可能是基于ID作为键的字典查找。这应该会加速处理,对吧?

我不清楚我每次都在销毁和重新创建数组的注释。那是$deadPaths数组吗?简单地加上它会导致这种情况吗?如果是这样的话,我使用.Net ArrayList会更好吗?

EN

回答 2

Stack Overflow用户

发布于 2015-12-22 16:46:14

我认为这将是你正在寻找的东西的开始。正如注释中所讨论的,我们将进行两次比较。首先,要获得BuildID,我们需要从$FSBuildIDs$blArray中进行比较,然后将结果与$paths列表进行比较。现在,我将假设它只是一个字符串路径数组。注意,这里有防止和纠正错误的空间。现在还只是测试。

代码语言:javascript
复制
$parsedIDs = Compare-Object $blArray $FSBuildIDs | Where{$_.SideIndicator -eq "=>"} | Select-Object -ExpandProperty InputObject

$paths = $paths | ForEach-Object{
    $_ | Add-Member -MemberType NoteProperty -Name BuildID -Value (($_.Parent.Name + $_.Name) -as [int32]) -PassThru
}

$paths | Where-Object{$_.BuildID -in $parsedIDs}

首先,我们比较了两个ID数组并保留了$FSBuildIDs的唯一元素。

接下来我们要通过$paths。对于每个属性,我们都添加了一个包含buildid的属性。其中,buildid是连接并转换为整数的最后两个路径元素。

一旦我们有了它,一个简单的Where-Object就会给出从第一次比较中得到id的路径。

票数 0
EN

Stack Overflow用户

发布于 2015-12-22 17:00:17

要回答有关构建散列表的问题:

代码语言:javascript
复制
$keyEnumerator = $FSBuildIDs.GetEnumerator()
$valEnumerator = $paths.GetEnumerator()
$idPathHash = @{}

foreach ($key in $keyEnumerator ) {
  $null = $valEnumerator.movenext()
  $idPathHash[$key] = $valEnumerator.current
}

在我的系统上使用20000元素数组的假数据运行这段代码需要138 my。

要生成不在$idPathHash中的生成ids列表,请执行以下操作:

代码语言:javascript
复制
$buildIDsNotIn =
  foreach ($buildId in $blArray) {
    if (!$idPathHash.ContainsKey($buildId )) {
      $buildId 
    } 
  }

这在我的系统上花费了50毫秒,$blArray中有20000个条目,还有假数据。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34417901

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档