找到以相同值开头的对象,并在数组中保留最长的值。Powershell

huangapple go评论65阅读模式
英文:

Find objects that start with the same value and keep only the longest value in the array Powershell

问题

我正在尝试找到一个筛选我的数组的解决方案。

对于筛选条件,它将是:如果第3列的一个对象与该列的另一个对象匹配(或包含)。然后删除它。

以下是$data的示例:

By      Mode File
--      ---- ----
user1   Read creation. ABC
user1   Read creation. ABC\Invoice
user1   Read creation. ABC\LIMITED
user2   Read edition\File
user2   Read edition\File\DATA SHEETS
user2   Read BCD
user2   Read BCD\DATA
user3   Read BCD

我想要删除具有相同开头的对象,只保留具有最多字符的对象。但是,如果不是同一用户,不应筛选该行。

我希望作为结果得到:

By      Mode File
--      ---- ----
user1   Read creation. ABC\Invoice
user1   Read creation. ABC\LIMITED
user2   Read edition\File\DATA SHEETS
user2   Read BCD\DATA
user3   Read BCD

我尝试过:

foreach($elem in $data.file)
{
$data.file.Where({$_.contains($elem)}, 'First',3)
}

我被卡住了,感谢您的建议。

英文:

I am trying to find a solution to filter my array.

For the criterion it would be: if an object of the 3rd column matches (or contains) with another object of this same column. Then delete it.

Here is an example of $data:

By      Mode File
--      ---- ----
user1 	Read creation. ABC
user1 	Read creation. ABC\Invoice
user1 	Read creation. ABC\LIMITED
user2   Read edition\File
user2   Read edition\File\DATA SHEETS
user2   Read BCD
user2	Read BCD\DATA
user3	Read BCD

I want to delete the objects which have an identical beginning by keeping only the one which has the most characters.
However, if it is not the same user, the line should not be filtered.

what I am looking for as a result :

By      Mode File
--      ---- ----
user1 	Read creation. ABC\Invoice
user1 	Read creation. ABC\LIMITED
user2   Read edition\File\DATA SHEETS
user2	Read BCD\DATA
user3	Read BCD

What I tried :

foreach($elem in $data.file)
{
$data.file.Where({$_.contains($elem)}, 'First',3)
}

I am stuck, thank you for your comments

答案1

得分: 4

以下是您要求的翻译内容:

<!-- language-all: sh -->

在得到有用的评论后,我认为这就是您要找的内容,假设我们有示例输入存储在名为CSV的变量中:

```powershell
$csv = ConvertFrom-Csv @'
By,Mode,File
user1,Read,creation. ABC
user1,Read,creation. ABC\Invoice
user1,Read,creation. ABC\LIMITED
user2,Read,edition\File
user2,Read,edition\File\DATA SHEETS
user2,Read,BCD
user2,Read,BCD\DATA
user3,Read,BCD
'@

我们可以使用Group-ObjectSort-ObjectString.StartsWith的组合:

# 使用 `By` 属性对对象进行分组并枚举它们
$csv | Group-Object By | ForEach-Object {
    # 对组按 `File` 属性进行排序(升序)
    $sorted = @($_.Group | Sort-Object File)
    # 并枚举每个组
    for($i = 0; $i -lt $sorted.Count; $i++) {
        # 存储当前项
        $current = $sorted[$i]
        # 以及此集合中的下一项
        $next = $sorted[$i + 1]
        # 如果此组中有下一项,并且下一项的 `File` 属性以与当前项相同的字符串开头
        # 例如:`'edition\File\DATA SHEETS'.StartsWith('edition\File')`
        if($next -and $next.File.StartsWith($current.File, [StringComparison]::InvariantCultureIgnoreCase)) {
            # 我们可以假定这个可以跳过
            continue
        }
        # 否则,输出它
        $current
    }
}

这个示例产生的输出将是:

By    Mode File
--    ---- ----
user1 Read creation. ABC\Invoice
user1 Read creation. ABC\LIMITED
user2 Read BCD\DATA
user2 Read edition\File\DATA SHEETS
user3 Read BCD

请注意,我已经将代码部分保留在原文中,只翻译了相关的注释和文本。

<details>
<summary>英文:</summary>

&lt;!-- language-all: sh --&gt;

Following the helpful comments, I believe this is what you&#39;re looking for, assuming we have the example input stored in a variable called CSV:

$csv = ConvertFrom-Csv @'
By,Mode,File
user1,Read,creation\1. ABC
user1,Read,creation\1. ABC\Invoice
user1,Read,creation\1. ABC\LIMITED
user2,Read,edition\File
user2,Read,edition\File\DATA SHEETS
user2,Read,BCD
user2,Read,BCD\DATA
user3,Read,BCD
'@


We can use a combination of [`Group-Object`](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/group-object?view=powershell-7.3), [`Sort-Object`](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/sort-object?view=powershell-7.3) and [`String.StartsWith`](https://learn.microsoft.com/en-us/dotnet/api/system.string.startswith?view=net-8.0):

group the objects by the By property and enumerate them

$csv | Group-Object By | ForEach-Object {
# sort the groups by the File property (ascending)
$sorted = @($_.Group | Sort-Object File)
# and enumerate each group
for($i = 0; $i -lt $sorted.Count; $i++) {
# store the current item
$current = $sorted[$i]
# and the next item in this collection
$next = $sorted[$i + 1]
# if there is a next item in this group AND
# the next item File property starts with the same string as the current item
# i.e.: &#39;edition\File\DATA SHEETS&#39;.StartsWith(&#39;edition\File&#39;)
if($next -and $next.File.StartsWith($current.File, [StringComparison]::InvariantCultureIgnoreCase)) {
# we can assume this one can be skipped
continue
}
# else, output it
$current
}
}


The produced output from this example would be:

```none
By    Mode File
--    ---- ----
user1 Read creation. ABC\Invoice
user1 Read creation. ABC\LIMITED
user2 Read BCD\DATA
user2 Read edition\File\DATA SHEETS
user3 Read BCD

huangapple
  • 本文由 发表于 2023年5月7日 05:38:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/76191271.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定