выбор 2D-среза 2D-среза с использованием диапазонов на ходу - PullRequest
0 голосов
/ 04 февраля 2019

Я получаю неожиданный результат при выборе 2D-среза среза.Рассмотрим следующий 2D-массив int

a := [][]int{
    {0, 1, 2, 3},
    {1, 2, 3, 4},
    {2, 3, 4, 5},
    {3, 4, 5, 6},
}

. Чтобы выбрать верхний левый 3x3 2D-срез с использованием диапазонов, я бы использовал

b := a[0:2][0:2]

Я ожидал бы, что результат будет

[[0 1 2] [1 2 3] [2 3 4]]

однако второй диапазон индекса, похоже, не имеет никакого эффекта, а вместо этого возвращает следующее:

[[0 1 2 3] [1 2 3 4] [2 3 4 5]]

Чего мне не хватает?Можете ли вы просто не выбирать подобласти, где размерность> 1?

1 Ответ

0 голосов
/ 04 февраля 2019

Вы не можете делать то, что хотите, за один шаг.Ломтики и массивы не являются двумерными, они просто составлены для формирования многомерного объекта.См. Как выглядит представление памяти двумерного массива

Итак, с выражением среза, вы просто получите срез, который будет содержать подмножество «полных» строк, и его тип будет таким же: [][]int.Если вы нарежете его снова, вы просто нарежете фрагмент строки снова.

Также обратите внимание, что более высокий индекс в выражении фрагмента является эксклюзивным, поэтому a[0:2] будет иметь только 2 строки, поэтому вы должны использовать a[0:3] или просто a[:3] вместо.

Чтобы получить то, что вы хотите, вы должны нарезать строки по отдельности следующим образом:

b := a[0:3]
for i := range b {
    b[i] = b[i][0:3]
}
fmt.Println(b)

Это выведет (попробуйте на Go Playground ):

[[0 1 2] [1 2 3] [2 3 4]]

или короче:

b := a[:3]
for i, bi := range b {
    b[i] = bi[:3]
}
...