Получить индексы повторяющихся значений в массиве - PullRequest
0 голосов
/ 16 октября 2019

Я хочу найти индексы повторяющихся значений в массиве.

Например

Ввод:

$data = @(1, 2, 3, 2, 1)

Выход:

$indexes = @(3, 4)

Ответы [ 3 ]

1 голос
/ 16 октября 2019

Для другого подхода вы можете использовать try-catch блоки с хеш-таблицей.

$data = @(1, 2, 3, 2, 1)
$hash = @{}
$indexes = for ($i = 0; $i -lt $data.count; $i++ ) {
    try {
        $hash.add($data[$i],$i)
    } 
    catch {
        $i
        continue
    }
}

# Output

$indexes
3
4

Идея состоит в том, чтобы добавить каждое значение в качестве ключа и соответствующий индекс в качестве значения в хешТаблица. Поскольку у объекта [hashtable] могут быть только уникальные ключи, будет сгенерировано исключение. В блоке catch мы просто выводим индекс, который в конечном итоге сохраняется в $indexes. Оператор continue позволяет циклу увеличивать и продолжать обработку.


С точки зрения алгоритма это решение практически идентично уже предложенному решению. Однако он использует более эффективный Add() метод [arraylist], а не перестраивает (+=) [array] во время каждой итерации. Производительность незначительна в этом примере, но может стоить рассмотреть в больших наборах данных. При этом также выбирается традиционный цикл for вместо foreach.

$uniqueValues = [collections.arraylist]@()

$indexes = for ($i = 0; $i -lt $data.count; $i++) {
    if ($uniqueValues -contains $data[$i]) {
        $i
    } 
    else {
        [void]$uniqueValues.Add($data[$i])
    }
}

# Output
$indexes
3
4

. В этом решении поддерживается [arraylist] уникальных значений ($uniqueValues). Любое значение, которое не является уникальным, его индекс ($i) выводится и сохраняется в $indexes. Уникальность определяется с помощью оператора -contains для сравнения текущего значения в итерации $data с тем, что уже находится в $uniqueValues.

1 голос
/ 16 октября 2019

Вы также можете использовать Hashtable для этого:

$data = 1, 2, 3, 2, 1
$hash = @{}
$indexes = for ($i = 0; $i -lt $data.Count; $i++) {
    # the value you store in the $hash in the else block is not important
    if ($hash.ContainsKey($data[$i])) { $i } else {$hash[$data[$i]] = $true}
}
$indexes

Результат:

3
4
0 голосов
/ 16 октября 2019

Цикл Foreach с if внутри должен выполнять работу:

$data = @(1, 2, 3, 2, 1)
$uniqueValues = @()
$duplicatesIndexes = @()
$data | ForEach-Object {$counter = 0}{
  if ($_ -notin $uniqueValues) {
    $uniqueValues += $_
  } else {
    $duplicatesIndexes += $counter
  }
  $counter++
}

# Output
PS> $duplicatesIndexes
3
4
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...