Найдите объекты, которые начинаются с одного и того же значения, и сохраните только самое длинное значение в массиве Powershell

Я пытаюсь найти решение для фильтрации моего массива.

Для критерия это будет: если объект 3-го столбца совпадает (или содержит) с другим объектом этого же столбца. Затем удалите его.

Вот пример $data:

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

Я хочу удалить объекты с одинаковым началом, оставив только тот, у которого больше всего символов. Однако, если это не один и тот же пользователь, строку фильтровать не следует.

что я ищу в результате:

By      Mode File
--      ---- ----
user1   Read creation\1. ABC\Invoice
user1   Read creation\1. 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)
}

Я застрял, спасибо за ваши комментарии

Я хочу сохранить «user2 Read BCD\DATA» и удалить «user2 Read BCD», потому что это похоже на дубликат

Cora_beeetle 06.05.2023 23:59

это нелегко объяснить. Я хочу отфильтровать свой массив. Для этого я хочу удалить объекты с одинаковым началом, оставив только тот, у которого больше всего символов. Извините за сумбурные объяснения.

Cora_beeetle 07.05.2023 00:02

Вам придется использовать break/parse по длине этого третьего столбца, и, как указывает Олаф, используйте Group-By для этого результата.

postanote 07.05.2023 00:09

Для критерия это будет: если объект 3-го столбца совпадает (или содержит) с другим объектом этого же столбца. Затем удалите его.

Cora_beeetle 07.05.2023 00:16

спасибо за попытку и поощрение меня совершенствоваться, чтобы детализировать лучше. Эта строка «user2 Read BCD» существует в этом «user2 Read BCD\DATA». Поэтому я хочу удалить его.

Cora_beeetle 07.05.2023 00:24
Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
2
5
55
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Следуя полезным комментариям, я считаю, что это то, что вы ищете, предполагая, что у нас есть ввод примера, хранящийся в переменной с именем 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
'@

Мы можем использовать комбинацию Group-Object , Sort-Object и String.StartsWith:

# 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.: `'edition\File\DATA SHEETS'.StartsWith('edition\File')`
        if ($next -and $next.File.StartsWith($current.File, [StringComparison]::InvariantCultureIgnoreCase)) {
            # we can assume this one can be skipped
            continue
        }
        # else, output it
        $current
    }
}

Результатом этого примера будет:

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

действительно впечатляет. огромное спасибо Производственный тест работает отлично. В powershell есть за что любить!

Cora_beeetle 07.05.2023 00:37

@Cora_beeetle ❤️ это, безусловно, отличный язык! В .NET тоже есть за что любить, хе-хе.

Santiago Squarzon 07.05.2023 00:40

Сантьяго Скуарсон за победу. ;-}... но знайте, что это только для PowerShellCore. Windows PS5x не нравится. ;-} Это просто кричит, когда вы жалуетесь на Index was outside the bounds of the array. для каждого пользователя. Это было то, над чем я работал, вы знаете, пытаясь обеспечить кроссплатформенность и компактность в обратном направлении (на случай, если постер застрял на устаревшей PS), написал Сантьяго Скуарзон.

postanote 07.05.2023 02:42

@postanote спасибо, но вы уверены, что это только 7+? это отлично работает для меня в 5.1. может произойти сбой только при использовании строгого режима, в противном случае он работает в обеих версиях;)

Santiago Squarzon 07.05.2023 02:54

Я провел тест на двух моих машинах PS5x, и на обоих он не прошел. Как правило, у меня всегда есть StrictMode во всех моих профилях машины разработчика. Вы знаете, просто чтобы держать меня под контролем, пока я кодирую. ;-} Я только что выполнил это в своей песочнице Windows по умолчанию, без настроек профиля, тогда это работает, как и ожидалось.

postanote 07.05.2023 21:13

@postanote да, имеет смысл, что в StrictMode это не удастся. лично я им никогда не пользуюсь

Santiago Squarzon 07.05.2023 21:18

Другие вопросы по теме