2D-массив в Котлине

Как вы делаете 2D-массив в Kotlin? Я пытаюсь преобразовать этот код в Kotlin:

    int[][] states = new int[][] {
        new int[]{-android.R.attr.state_pressed}, // not pressed
        new int[] { android.R.attr.state_pressed}  // pressed
    };
    int[] colors = new int[] {
        foregroundColor,
        accentColor,
        accentColor
    };
    ColorStateList myList = new ColorStateList(states, colors);

Вот одна попытка, которую я попытался, где первый 2D-массив не работал, но я получил 1D-массив:

    //This doesn't work:
    var states: IntArray = intArrayOf(
        intArrayOf(-android.R.attr.state_pressed), // not pressed
        intArrayOf(android.R.attr.state_pressed)  // pressed
    );
    //This array works:
    var colors: IntArray = intArrayOf(
        foregroundColor,
        accentColor,
        accentColor
    );
    val myList: ColorStateList = ColorStateList(states, colors);

Ответ 1

Вы пытаетесь поместить свои IntArrays внутри другого массива, чтобы сделать его двумерным. Тип этого массива не может быть intArray, поэтому это не удается. Оберните свои начальные массивы с помощью arrayOf вместо intArrayOf.

val even: IntArray = intArrayOf(2, 4, 6)
val odd: IntArray = intArrayOf(1, 3, 5)

val lala: Array<IntArray> = arrayOf(even, odd)

Ответ 2

Вы можете использовать эту строку кода для массива Integer.

val array = Array(row, {IntArray(column)})

Эта строка кода довольно проста и работает как массив 1D, а также может быть доступна как Java-массив Java.

Ответ 3

1. Вложенный arrayOf вызовов

Вы можете arrayOf вызовы arrayOf, например, для создания массива IntArray, выполните следующие действия:

val first: Array<IntArray> = arrayOf(
    intArrayOf(2, 4, 6),
    intArrayOf(1, 3, 5)
)

Обратите внимание, что сам IntArray принимает в качестве аргументов только аргументы типа Int, поэтому у вас не может быть IntArray<IntArray> который, очевидно, в любом случае не имеет особого смысла.

2. Используйте Array::constructor(size: Int, init: (Int) → T) для повторной логики

Если вы хотите создать свои внутренние массивы с некоторым логическим поведением на основе индекса, вы можете использовать конструктор Array с размером и блоком init:

val second: Array<IntArray> = Array(3) {
    intArrayOf(it * 1, it * 2, it * 3, it * 4)
} 
//[[0, 0, 0, 0], [1, 2, 3, 4], [2, 4, 6, 8]]

Ответ 4

Кажется, вы пытаетесь создать ColorStateList в Котлине. Код немного грязный, я постараюсь сохранить его читабельным:

val resolvedColor = Color.rgb(214,0,0)
val states = arrayOf(
    intArrayOf(-android.R.attr.state_pressed),
    intArrayOf(android.R.attr.state_pressed)
)

val csl = ColorStateList(
    states,
    intArrayOf(resolvedColor, Color.WHITE)
)

Ответ 5

Короткий ответ:

// A 6x5 array of Int, all set to 0.
var m = Array(6) {Array(5) {0} }

Вот еще один пример с более подробной информацией о том, что происходит:

// a 6x5 Int array initialise all to 0
var m = Array(6, {i -> Array(5, {j -> 0})})

Первый параметр - это размер, второй лямбда-метод - для инициализации.

Ответ 6

Я использовал этот однострочник при создании матрицы

var matrix: Array<IntArray> = Array(height) { IntArray(width) }

Ответ 7

Вы можете использовать простой одномерный (линейный) массив для этой цели. Например, это мой класс для прямоугольного массива значений Double:

/**
 * Rect array of Double values
 */
class DoubleRectArray(private val rows: Int, private val cols: Int) {
    private val innerArray: DoubleArray

    init {
        if(rows < 1) {
            throw IllegalArgumentException("Rows value is invalid. It must be greater than 0")
        }

        if(cols < 1) {
            throw IllegalArgumentException("Cols value is invalid. It must be greater than 0")
        }

        innerArray = DoubleArray(rows*cols)
    }

    /**
     *
     */
    fun get(row: Int, col: Int): Double {
        checkRowAndCol(row, col)
        return innerArray[row*cols + col]
    }

    /**
     *
     */
    fun set(row: Int, col: Int, value: Double) {
        checkRowAndCol(row, col)
        innerArray[row*cols + col] = value
    }

    /**
     *
     */
    private fun checkRowAndCol(row: Int, col: Int) {
        if(row !in 0 until rows) {
            throw ArrayIndexOutOfBoundsException("Row value is invalid. It must be in a 0..${rows-1} interval (inclusive)")
        }

        if(col !in 0 until cols) {
            throw ArrayIndexOutOfBoundsException("Col value is invalid. It must be in a 0..${cols-1} interval (inclusive)")
        }
    }
}

Ответ 8

Вы можете создать два одномерных массива и добавить их в новый массив.

val unChecked = intArrayOf(-android.R.attr.state_checked)
val checked = intArrayOf(android.R.attr.state_checked)
val states = arrayOf(unChecked, checked)

val thumbColors = intArrayOf(Color.WHITE, Color.parseColor("#55FFD4"))
val stateList = ColorStateList(states, thumbColors)