我在看这个问题,OP 想知道如何比较两个数组中的项目而不循环每个数组。
给出的命令是:
$array3 = @(Compare-Object $array1 $array2 | select -Expand InputObject
我的问题有两个:
一,这真的避免了以任何形式遍历数组吗?或者它只是通过在幕后进行操作来混淆用户的操作。
二,就性能而言,这是比较对象的最佳方法吗?在我看来,它实际上要慢得多。
我做了一个真正的粗略测试:
$Array1 = @("1","2","Orchid","Envy","Sam","Map Of the World","Short String","s","V","DM","qwerty","1234567891011")
$Array2 = @("Bob", "Helmet", "Jane")
$Date1 = Get-Date
$Array2 | ForEach-Object `
{
if ($Array1 -contains $_){}
}
$Date2 = Get-Date
$Time1 = [TimeSpan]$Date2.Subtract($Date1)
Write-Host $Time1
$Date1 = Get-Date
$Array3 = @(Compare-Object $Array1 $Array2)
$Date2 = Get-Date
$Time2 = [TimeSpan]$Date2.Subtract($Date1)
Write-Host $Time2
我的时代出来了:
ForEach-对象:00:00:00.0030001
比较对象:00:00:00.0030002
编辑
我更新了脚本以使其更公平,它基本上平衡了时间。
那么 Compare-Object 和传统循环之间的幕后区别是什么?我假设没有正确吗?
编辑 2
我使用反编译器找到了这段代码:
internal int Compare(ObjectCommandPropertyValue first, ObjectCommandPropertyValue second)
{
if (first.IsExistingProperty && second.IsExistingProperty)
return this.Compare(first.PropertyValue, second.PropertyValue);
if (first.IsExistingProperty)
return -1;
return second.IsExistingProperty ? 1 : 0;
}
public int Compare(object first, object second)
{
if (ObjectCommandComparer.IsValueNull(first) && ObjectCommandComparer.IsValueNull(second))
return 0;
PSObject psObject1 = first as PSObject;
if (psObject1 != null)
first = psObject1.BaseObject;
PSObject psObject2 = second as PSObject;
if (psObject2 != null)
second = psObject2.BaseObject;
try
{
return LanguagePrimitives.Compare(first, second, !this.caseSensitive, (IFormatProvider) this.cultureInfo) * (this.ascendingOrder ? 1 : -1);
}
catch (InvalidCastException ex)
{
}
catch (ArgumentException ex)
{
}
return string.Compare(((object) PSObject.AsPSObject(first)).ToString(), ((object) PSObject.AsPSObject(second)).ToString(), !this.caseSensitive, this.cultureInfo) * (this.ascendingOrder ? 1 : -1);
}
我已经尽可能地追踪它,我相信这是两个工作线程。看起来 Compare-Object 实际上只执行 1 <==> 1 检查列表。我在这里错过了什么吗?