在 Kotlin 中使用带有条件的 lambda 初始化数组
Initializing an Array using lambda with conditions in Kotlin
信息
我有一个项目 class 文件如下:
class Item(var color:String, var numValue:Int, var drawableID:Int){
init {
color = this.color
numValue = this.numValue
drawableID = this.drawableID
}
}
在主要代码中,我创建了一个默认属性包含 104 个对象的数组:
var myItemClassArray = Array(104) { Item("", -99, -99) }
我的 drawable 文件夹中也有图片,它们的 ID 在数组中 drawablesIDs:Array<Int>
,它包含 53 个元素。
问题
我想分配我的项目属性,如下图所示:https://i.stack.imgur.com/wFVsn.png我可以使用下面给出的代码来解决类似的问题(有 106 个对象和 53 个可绘制对象):
for (i in 0 until 106) {
if (i < 13) {
myItemClassList[i+2].color = "kirmizi"
myItemClassList[i+2].numValue = i+1
myItemClassList[i+2].drawableID = drawablesIDs[i+1]
} else if (i in 13..25) {
myItemClassList[i+2].color = "siyah"
myItemClassList[i+2].numValue = (i+1)-13
myItemClassList[i+2].drawableID = drawablesIDs[i+1]
} else if (i in 26..38) {
myItemClassList[i+2].color = "yesil"
myItemClassList[i+2].numValue = (i+1)-26
myItemClassList[i+2].drawableID = drawablesIDs[i+1]
} else if (i in 39..51) {
myItemClassList[i+2].color = "mavi"
myItemClassList[i+2].numValue = (i+1)-39
myItemClassList[i+2].drawableID = drawablesIDs[i+1]
} else if (i in 52..64) {
myItemClassList[i+2].color = "kirmizi"
myItemClassList[i+2].numValue = (i+1)-52
myItemClassList[i+2].drawableID = drawablesIDs[(i+1)-52]
} else if (i in 65..77) {
myItemClassList[i+2].color = "siyah"
myItemClassList[i+2].numValue = (i+1)-65
myItemClassList[i+2].drawableID = drawablesIDs[i+1-65+13]
} else if (i in 78..90) {
myItemClassList[i+2].color = "yesil"
myItemClassList[i+2].numValue = (i+1)-78
myItemClassList[i+2].drawableID = drawablesIDs[i+1-78+26]
} else if (i in 91..103) {
myItemClassList[i+2].color = "mavi"
myItemClassList[i+2].numValue = (i+1)-91
myItemClassList[i+2].drawableID = drawablesIDs[i+1-91+39]
} else {
myItemClassList[0].color = "sahte"
myItemClassList[0].drawableID = drawablesIDs[0]
myItemClassList[1].color = "sahte"
myItemClassList[1].drawableID = drawablesIDs[0]
}
}
有更简洁的方法吗?
可以使用 lambda 表达式创建数组。例如:
val test = Array(28){i-> examples[i]}
使用一个 "i" 参数就可以正常工作。但是如果我想尝试这样的事情:
val test = Array(28){if(i<13)-> examples[i]}
它给我一个错误,因为它的语法是错误的。
更简单的问题
假设我们有一个数组,其中包含从 0 到 28 的数字,如下所示:
val testNumbers= Array(28){i->i}
现在我想使用 lambda 创建一个包含从 0 到 10 的数字的数组。
我该怎么做:
val player6 = Array(10){(it<10) -> testNumbers[it]} // gives an syntax error
这是一个可能的解决方案:
fun getColor(i: Int) = when (i) {
in 0..1 -> "sahte"
in 2..13, in 52..64 -> "kirmizi"
in 65..77, in 13..25 -> "siyah"
in 26..38, in 78..90 -> "yesil"
in 39..51, in 91..103 -> "mavi"
else -> ""
}
fun getNumValue(i: Int) = when (i) {
in 0..1 -> -99
in 2..13 -> i - 1
in 13..25 -> (i - 1) - 13
in 26..38 -> (i - 1) - 26
in 39..51 -> (i - 1) - 39
in 52..64 -> (i - 1) - 52
in 65..77 -> (i - 1) - 65
in 78..90 -> (i - 1) - 78
in 91..103 -> (i - 1) - 91
else -> -99
}
fun getDrawableID(i: Int) = when (i) {
in 0..1 -> drawablesIDs[0]
in 2..13, in 13..25, in 26..38, in 39..51 -> drawablesIDs[i - 1]
in 52..64 -> drawablesIDs[(i - 1) - 52]
in 65..77 -> drawablesIDs[i - 1 - 65 + 13]
in 78..90 -> drawablesIDs[i - 1 - 78 + 26]
in 91..103 -> drawablesIDs[i - 1 - 91 + 39]
else -> -99
}
val myItemClassArray = Array(104) {
Item(getColor(it), getNumValue(it), getDrawableID(it))
}
可能在不同的范围内有一些错误。
主要优点是:
- 每个映射都可以独立测试
- 无可变性
根据我从你的照片中收集到的信息,我做出了以下三个假设:
- numValue 以 13 项为一组进行分组
- 每组获得一种颜色,顺序为:kirmizi -> siyah -> yesil -> mavi,然后再次循环
- 可绘制 ID 每 52 个项目循环一次
基于此,我想出了以下解决方案:
data class Item(var color: String = "", var numValue: Int = -99, var drawableId: Int = -99)
fun main() {
val colors = listOf("kirmizi", "siyah", "yesil", "mavi")
val drawableIDs = (0..52).toList() // This is just a stub. in your case it will be your drawable lists
val edgeCase = arrayListOf(Item("sahte", drawableId = drawableIDs[0]), Item("sahte", drawableId = drawableIDs[0]))
val pattern = (0 until 104)
.map { index -> Pair(index, index / 13) }
.map { (index, group) ->
Item(
color = colors[group % 4],
numValue = index+1,
drawableId = drawableIDs[(index % 52) + 1]
)
}
val total = pattern + edgeCase
total.forEach { println(it) }
}
您可以在此 kotlin playground.
上使用它
Is there a cleaner way to do this?
据我所知,您只想初始化具有 28 个空格的连续数组的前 13 个值,而将其余值保留为默认值或 null。
您的代码不起作用的原因是因为 Array
初始化器希望您 return 一个对象。 if
块本身不是 kotlin 中的表达式,因此它不会求值,因此您需要提供一个 else
分支才能使其工作。
val examples = Array(28) { if (i < 13) examples[i] else defaultExample }
这在 Kotlin documentation for control flow 中说明:
If you're using if as an expression rather than a statement (for example, returning its value or assigning it to a variable), the expression is required to have an else branch.
More simple question
在这种情况下,您可以只使用 take:
// If you don't want to modify it
val player6 = testNumbers.take(10)
.toTypedArray() // Since take returns a List, you need to turn it back into an array
// If you want to modify the items
val player6 = testNumbers.take(10)
.map { value -> modifyNumber(value) }
.toTypedArray()
提示: 在 kotlin 中,如果您使用 val
或 var
声明构造函数参数,它们已经是您的 class 的属性,并且您不需要在 init
块中手动初始化。
/*
* You don't need to do this:
* class Item(var color: String, var numValue: Int, var drawableId: Int) {
* init {
* this.color = color
* this.numValue = numValue
* this.drawableId = drawableId
* }
* }
*/
// Kotlin already does it for you
class Item(var color: String, var numValue: Int, var drawableId: Int)
fun main() {
val myitem = Item("blue", 20, 100)
println(myitem.color)
println(myitem.numValue)
println(myitem.drawableId)
}
信息
我有一个项目 class 文件如下:
class Item(var color:String, var numValue:Int, var drawableID:Int){
init {
color = this.color
numValue = this.numValue
drawableID = this.drawableID
}
}
在主要代码中,我创建了一个默认属性包含 104 个对象的数组:
var myItemClassArray = Array(104) { Item("", -99, -99) }
我的 drawable 文件夹中也有图片,它们的 ID 在数组中 drawablesIDs:Array<Int>
,它包含 53 个元素。
问题
我想分配我的项目属性,如下图所示:https://i.stack.imgur.com/wFVsn.png我可以使用下面给出的代码来解决类似的问题(有 106 个对象和 53 个可绘制对象):
for (i in 0 until 106) {
if (i < 13) {
myItemClassList[i+2].color = "kirmizi"
myItemClassList[i+2].numValue = i+1
myItemClassList[i+2].drawableID = drawablesIDs[i+1]
} else if (i in 13..25) {
myItemClassList[i+2].color = "siyah"
myItemClassList[i+2].numValue = (i+1)-13
myItemClassList[i+2].drawableID = drawablesIDs[i+1]
} else if (i in 26..38) {
myItemClassList[i+2].color = "yesil"
myItemClassList[i+2].numValue = (i+1)-26
myItemClassList[i+2].drawableID = drawablesIDs[i+1]
} else if (i in 39..51) {
myItemClassList[i+2].color = "mavi"
myItemClassList[i+2].numValue = (i+1)-39
myItemClassList[i+2].drawableID = drawablesIDs[i+1]
} else if (i in 52..64) {
myItemClassList[i+2].color = "kirmizi"
myItemClassList[i+2].numValue = (i+1)-52
myItemClassList[i+2].drawableID = drawablesIDs[(i+1)-52]
} else if (i in 65..77) {
myItemClassList[i+2].color = "siyah"
myItemClassList[i+2].numValue = (i+1)-65
myItemClassList[i+2].drawableID = drawablesIDs[i+1-65+13]
} else if (i in 78..90) {
myItemClassList[i+2].color = "yesil"
myItemClassList[i+2].numValue = (i+1)-78
myItemClassList[i+2].drawableID = drawablesIDs[i+1-78+26]
} else if (i in 91..103) {
myItemClassList[i+2].color = "mavi"
myItemClassList[i+2].numValue = (i+1)-91
myItemClassList[i+2].drawableID = drawablesIDs[i+1-91+39]
} else {
myItemClassList[0].color = "sahte"
myItemClassList[0].drawableID = drawablesIDs[0]
myItemClassList[1].color = "sahte"
myItemClassList[1].drawableID = drawablesIDs[0]
}
}
有更简洁的方法吗?
可以使用 lambda 表达式创建数组。例如:
val test = Array(28){i-> examples[i]}
使用一个 "i" 参数就可以正常工作。但是如果我想尝试这样的事情:
val test = Array(28){if(i<13)-> examples[i]}
它给我一个错误,因为它的语法是错误的。
更简单的问题
假设我们有一个数组,其中包含从 0 到 28 的数字,如下所示:
val testNumbers= Array(28){i->i}
现在我想使用 lambda 创建一个包含从 0 到 10 的数字的数组。 我该怎么做:
val player6 = Array(10){(it<10) -> testNumbers[it]} // gives an syntax error
这是一个可能的解决方案:
fun getColor(i: Int) = when (i) {
in 0..1 -> "sahte"
in 2..13, in 52..64 -> "kirmizi"
in 65..77, in 13..25 -> "siyah"
in 26..38, in 78..90 -> "yesil"
in 39..51, in 91..103 -> "mavi"
else -> ""
}
fun getNumValue(i: Int) = when (i) {
in 0..1 -> -99
in 2..13 -> i - 1
in 13..25 -> (i - 1) - 13
in 26..38 -> (i - 1) - 26
in 39..51 -> (i - 1) - 39
in 52..64 -> (i - 1) - 52
in 65..77 -> (i - 1) - 65
in 78..90 -> (i - 1) - 78
in 91..103 -> (i - 1) - 91
else -> -99
}
fun getDrawableID(i: Int) = when (i) {
in 0..1 -> drawablesIDs[0]
in 2..13, in 13..25, in 26..38, in 39..51 -> drawablesIDs[i - 1]
in 52..64 -> drawablesIDs[(i - 1) - 52]
in 65..77 -> drawablesIDs[i - 1 - 65 + 13]
in 78..90 -> drawablesIDs[i - 1 - 78 + 26]
in 91..103 -> drawablesIDs[i - 1 - 91 + 39]
else -> -99
}
val myItemClassArray = Array(104) {
Item(getColor(it), getNumValue(it), getDrawableID(it))
}
可能在不同的范围内有一些错误。
主要优点是:
- 每个映射都可以独立测试
- 无可变性
根据我从你的照片中收集到的信息,我做出了以下三个假设:
- numValue 以 13 项为一组进行分组
- 每组获得一种颜色,顺序为:kirmizi -> siyah -> yesil -> mavi,然后再次循环
- 可绘制 ID 每 52 个项目循环一次
基于此,我想出了以下解决方案:
data class Item(var color: String = "", var numValue: Int = -99, var drawableId: Int = -99)
fun main() {
val colors = listOf("kirmizi", "siyah", "yesil", "mavi")
val drawableIDs = (0..52).toList() // This is just a stub. in your case it will be your drawable lists
val edgeCase = arrayListOf(Item("sahte", drawableId = drawableIDs[0]), Item("sahte", drawableId = drawableIDs[0]))
val pattern = (0 until 104)
.map { index -> Pair(index, index / 13) }
.map { (index, group) ->
Item(
color = colors[group % 4],
numValue = index+1,
drawableId = drawableIDs[(index % 52) + 1]
)
}
val total = pattern + edgeCase
total.forEach { println(it) }
}
您可以在此 kotlin playground.
上使用它Is there a cleaner way to do this?
据我所知,您只想初始化具有 28 个空格的连续数组的前 13 个值,而将其余值保留为默认值或 null。
您的代码不起作用的原因是因为 Array
初始化器希望您 return 一个对象。 if
块本身不是 kotlin 中的表达式,因此它不会求值,因此您需要提供一个 else
分支才能使其工作。
val examples = Array(28) { if (i < 13) examples[i] else defaultExample }
这在 Kotlin documentation for control flow 中说明:
If you're using if as an expression rather than a statement (for example, returning its value or assigning it to a variable), the expression is required to have an else branch.
More simple question
在这种情况下,您可以只使用 take:
// If you don't want to modify it
val player6 = testNumbers.take(10)
.toTypedArray() // Since take returns a List, you need to turn it back into an array
// If you want to modify the items
val player6 = testNumbers.take(10)
.map { value -> modifyNumber(value) }
.toTypedArray()
提示: 在 kotlin 中,如果您使用 val
或 var
声明构造函数参数,它们已经是您的 class 的属性,并且您不需要在 init
块中手动初始化。
/*
* You don't need to do this:
* class Item(var color: String, var numValue: Int, var drawableId: Int) {
* init {
* this.color = color
* this.numValue = numValue
* this.drawableId = drawableId
* }
* }
*/
// Kotlin already does it for you
class Item(var color: String, var numValue: Int, var drawableId: Int)
fun main() {
val myitem = Item("blue", 20, 100)
println(myitem.color)
println(myitem.numValue)
println(myitem.drawableId)
}