【问题标题】:Get index of object in Generic/List based on value of a property根据属性值获取 Generic/List 中对象的索引
【发布时间】:2020-05-24 11:55:44
【问题描述】:

我可以用我的类的实例填充Generic.List,每个实例在 ID 属性中都有一个唯一值,如下所示。

$packages = [System.Collections.Generic.List[object]]::New()

class Package {
    # Properties
    [String]$ID

    # Constructor
    Package ([String]$id) {
        $this.ID = $id
    }
}

foreach ($i in 65..90) {
    $packages.Add([Package]::New("$([char]$i)"))
}

现在我想按照$packages.IndexOf('C') 获取特定项目的索引。但是在 C# 中这样做似乎需要使用 lambda,而 PowerShell 似乎不支持。我宁愿不必初始化我自己的索引变量并遍历列表中的所有项目,检查它们的 ID 并沿途增加索引。但是,也许这就是使用仅带有本机 PS cmdlet 的 PowerShell 和仅使用 C# 之间的灰色地带,在这两个极端中您都错过了糖,而必须自己制作?

【问题讨论】:

    标签: powershell properties indexof generic-list


    【解决方案1】:

    您可以使用[scriptblock] 作为谓词:

    $packages.FindIndex({$args[0].ID -eq 'C'})
    # or
    $packages.FindIndex({param($item) $item.ID -eq 'C'})
    

    假设您的包 ID 是唯一的,请考虑使用字典而不是列表:

    $packages = [System.Collections.Generic.Dictionary[string,Package]]::new([StringComparer]::InvariantCultureIgnoreCase)
    
    class Package {
        # Properties
        [String]$ID
    
        # Constructor
        Package ([String]$id) {
            $this.ID = $id
        }
    }
    
    foreach ($i in 65..90) {
        $ID = "$([char]$i)"
        $packages.Add($ID, [Package]::new($ID))
    }
    

    现在您不再需要担心项目的位置,现在您可以简单地通过 ID 删除一个:

    $wasRemoved = $packages.Remove("C")
    

    Remove() 成功删除条目时返回 $true,未找到密钥时返回 $false

    【讨论】:

    • 啊哈。我找到了一些关于使用这样的脚本块的信息,但它不适用于这个特定的用例,而且它不起作用。不是因为脚本块方法不起作用,而是因为您需要使用 FindIndex。哇!
    • 是的,您需要寻找将委托(System.PredicateSystem.Func 等)作为参数的方法签名 :)
    • 我学到了很多东西,因为我试图在课堂上全神贯注。现在我需要弄清楚如何多次.RemoveAt(),这就是我需要索引的原因。在我再次回来之前,我会为此努力一个小时左右。 ;-)
    • @Gordon 听起来您可以从字典中组织对象而不是列表中受益
    • @mathias-r-jessen 这是一个很好的观点。它也将简化我的数据验证,因为现在我必须测试是否有重复的 ID,使用有序字典我可以尝试/捕获。我想我现在真的会玩这个。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-12
    • 2021-03-18
    • 1970-01-01
    • 2018-01-15
    • 2020-02-02
    • 2016-10-31
    • 1970-01-01
    相关资源
    最近更新 更多