【问题标题】:Compare two arrays, if values are in array, add to list, if not add values to another list. No duplicates比较两个数组,如果值在数组中,则添加到列表中,如果不是,则将值添加到另一个列表中。没有重复
【发布时间】:2021-12-07 18:18:49
【问题描述】:

请查看代码中的 cmets,看看是否可以帮助我 我正在检查 $arr1 中的值是否在 $arr2 中。如果是,请将其添加到列表中, 如果不是,请将其添加到另一个列表中。确保两个列表/数组都没有 重复。

$arr1 = @(1,2,3,4,4,2,5,7,9,9,1) 
$arr2= @(5,1,2,3,6,8,1) 
$NotinList = @()
$inList = @()
$counter = 0

for ($i = 0; $i -lt $arr1.length; $i++){
    for( $j = 0; $j -lt $arr2.length; $j++ ){  
        if($arr1[$i] -ne $arr2[$j]){ #check to see if value from $arr1 is in $arr2
            for($k = 0; $k -lt $NotinList.length; $k++){ #Traverse through empty array
                write-host $arr1[$i]  
                if($NotinList[$k] -ne $arr1[$i]){                                        # *^ if empty array does not alreadycontain item from big $arr1, add it.
                    $NotinList +=  $arr1[$i]
                }
            }
        }
        else{
            $inList += $arr1[$i]

            #how would I remove duplicates from number in list since there are repeating numbers in $arr1 that are not in $arr2.

        }
}
$counter++ #keep track may use for something else??
}                

【问题讨论】:

  • 对于与previous one 几乎完全相同的问题,您已经得到了两个答案,并且两个答案都满足了您的需求。
  • 甚至没有关闭。我不想执行那些操作“.Add”操作我需要一切都在一定的时空复杂度内。我想以最有效的方式删除重复项。
  • 我已经有了完成工作的解决方案,但我想按照上面的方式进行。
  • 你不想做那些“添加”操作是什么意思?你在这里用 += 做的事情是在性能方面可以做的最糟糕的事情之一。更不用说“时空复杂度”了
  • 我不明白如何添加到 system.array 中,它实际上是在每次迭代时重新创建数组(您的代码片段)可以更有效地向通用列表添加值。

标签: arrays algorithm powershell multidimensional-array data-structures


【解决方案1】:

我会先消除重复项,然后使用Where() 数组运算符将数组拆分为变量。

$arr1 = 'a','b','b','c','d','e','e','f','g'
$arr2 = 'a','b','c','g'

# not in list = d, e, f
# in list = a, b, c, g

$inlist,$notinlist = ($arr1 | Get-Unique).Where({$_ -in $arr2},'split')

现在这里是每个包含的内容

$notinlist
d
e
f

$inlist
a
b
c
g

【讨论】:

  • 很好,这是一个很好的解决方案
  • 拆分调用非常聪明。
  • 很好,但请注意,由于问题中的$arr1排序,因此您不能使用Get-Unique(尝试1, 2, 1 | Get-Unique 来查看问题)- 要么使用排序输入或使用Select-Object -Unique(不幸的是,从PowerShell 7.2 开始,它的实现效率非常低 - 请参阅GitHub issue #11221)。根据数组的大小,在每个 .Where() 迭代中在另一个数组 (-in $arr2) 中执行线性查找可能会出现问题 - 但对于像样本数组一样小的数组绝对不是问题。
  • 或者([System.Collections.Generic.HashSet[string]]$arr1).where({....})也可以工作
  • 我明白了,sort-object -Unique 有效,但它比 select 更好吗?
【解决方案2】:

如果您坚持手动操作,我建议使用哈希表。它们速度极快,而且密钥必须是唯一的。

如果你关心订单,你可以使用[ordered] hashtables

$arr1 = 1,2,3,4,4,2,5,7,9,9,1
$arr2= 5,1,2,3,6,8,1

$inlist = [ordered]@{}
$notinlist = [ordered]@{}

foreach($entry in $arr1){
    if($entry -in $arr2){
        if($entry -notin $inlist.keys){
            $inlist.$entry = $entry
        }
    }
    else{
        if($entry -notin $notinlist.keys){
            $notinlist.$entry = $entry
        }
    }
}

现在您的唯一列表位于键或值中的一个/两个中

$inlist.Keys

1
2
3
5

$notinlist.Values

4
7
9

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-04
    • 1970-01-01
    • 1970-01-01
    • 2017-05-15
    • 1970-01-01
    • 2019-08-03
    相关资源
    最近更新 更多