$ Array.IndexOf неверно для индекса 0 с префиксом запятой

70
5

Я пытался добавить содержимое переменной в массив. Не зная, был ли еще инициализирован массив, я использовал трюк предшествующих данных для вставки с запятой, чтобы заставить его оценивать как массив. Похоже, что при этом, используя предыдущую запятую для вашего фактического элемента, метод indexof не дает правильный индекс для первого элемента массива.

В приведенном ниже примере кода $a показывает проблему, в то время как $b работает просто отлично; единственная разница - это предыдущая запятая при инициализации $a.

Это ошибка, или я чего-то не хватает?

PS C:\code> $a = (,4,5,6)
PS C:\code> $b = (4,5,6)
PS C:\code> $a
4
5
6
PS C:\code> $a.indexof(4)
-1
PS C:\code> $a.indexof(5)
1
PS C:\code> $a.indexof(6)
2
PS C:\code> $b
4
5
6
PS C:\code> $b.indexof(4)
0
PS C:\code> $b.indexof(5)
1
PS C:\code> $b.indexof(6)
2

Поскольку у меня проблема, я вместо этого просто префикс моей переменной с помощью [array] и избавился от префиксной запятой, и все выглядит хорошо. Мне просто интересно, что происходит.

спросил(а) 2016-02-25T20:38:00+03:00 4 года, 7 месяцев назад
1
Решение
98

Несколько вещей здесь, которые происходят, которые вносят свой вклад в вводящие в заблуждение результаты. Просто знайте, что такое поведение ожидается,

В вашем первом массиве $a вы создали 3 элемента. Первый из них имел унарный оператор. То, что вы на самом деле сделали, создано трехэлементным массивом, где первый элемент сам является целым массивом одного элемента. PowerShell делал вам одолжение и разворачивал массив, поэтому вывод $a и $b отображается на консоли одинаково.

PS M:\Scripts> $a = (,4,5,6)

PS M:\Scripts> $a[0].GetType().Fullname
System.Object[]

PS M:\Scripts> $a[1].GetType().Fullname
System.Int32

Итак, причина, по .IndexOf() метод .IndexOf() не нашел элемент 4, состоит в том, что он не вникает в вложенные массивы.

Ищет указанный объект и возвращает индекс его первого вхождения в одномерном массиве.

Казалось бы, по определению он не ищет вложенные массивы.

Если вам нужно это учитывать, вы можете использовать оператор -is или просто проверить тип.

PS M:\Scripts> $a | %{$_ -is [array]}
True
False
False

PS M:\Scripts> $a | %{$_.GetType().Fullname}
System.Object[]
System.Int32
System.Int32

Дело в том, что я не вижу здесь ошибки. Просто PowerShell очень приспособлен к тому, чтобы немного ввести в заблуждение.

ответил(а) 2016-02-25T22:32:00+03:00 4 года, 7 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема