2016-03-07 86 views
4

假设我有通过4个顶点的路径。在做快速原型我会在Java中定义了这个Kotlin和详细数组实例化

double[][] path = {{1.0, 2.0}, {1.0,3.0}, {3.0,4.0}, {8.0,9.0}} 

使用arrayOf,并doubleArrayOf功能在科特林相同的代码将

val path = arrayOf(doubleArrayOf(1.0, 2.0), doubleArrayOf(1.0, 2.0), doubleArrayOf(1.0,3.0), doubleArrayOf(8.0,9.0)) 

其中详细感觉有点。有没有解决这个问题的Kotlin方式?

编辑:用例在数字数据的“REPL like”环境中回答查询,即考虑Matlab或SciPy。

+0

我会用'data'类编写“正常”生产Kotlin代码,并归档“快速原型”的速度和简易性。不知道REPL的事情.. – voddan

+0

“REPL like”环境对于这个问题意味着什么,目前还不清楚这是如何影响可能的答案的。 –

+0

就像处理较短代码片段的科学工作流程一样,通常但不是在REPL中完成。基于预感,你形成了一个假设和一组测试假设的问题。为了试试你的问题,你可以模拟一些简单的测试数据。您在真实和测试数据上迭代几次。这个问题在程序上是微不足道的,而域是一个挑战。最后,通常会抛弃假设,然后继续前进。如果您击中黄金,那么您可以使用常规软件方法来构建服务。 –

回答

5

arrayOfdoubleArrayOf和其他类似的,只是stdlib中的顶级函数。为了缩短语法,你可以很容易地在顶层的函数内创建scope自己的函数,一个类中,甚至在本地:

通过创建:

fun pathOf(vararg points: DoubleArray): Array<out DoubleArray> = points 
fun pt(x: Double, y: Double) = doubleArrayOf(x,y) 

这样:

val path = pathOf(pt(1.0, 2.0), pt(1.0, 2.0), pt(1.0, 3.0), pt(8.0, 9.0)) 

现在给出了未来读者或代码的嵌套数组意义。将函数命名为point,pt,xy,或其他任何适合您的用例的函数。

此代码只比原来的,也许稍长比Java更可读/意味深长:

double[][] path = {{1.0, 2.0}, {1.0, 3.0}, {3.0, 4.0}, {8.0, 9.0}} 

这些功能都只是尽可能高效利用arrayOfdoubleArrayOf,如果反复使用的JVM终将inline他们,但如果你很紧张,你可以自己让他们inline

Kotlin的目标是延长,任何时候遇到这样的问题时都会考虑如何扩展API或更改函数以获得所需的可读性。

+0

这是一个明显的答案。用例是在数字大数据的“REPL like”环境中回答查询,即考虑Matlab或numpy。我使用的当前解决方案是为数组创建设置通用的短手函数,如fun d(vararg v:Double)= doubleArrayOf(* v)'和fun f(vararg v:Float)= floatArrayOf(* v) '。有时候我会感觉到Kotlin一方面给予了什么,即操作符重载和中缀,而另一方面则需要数组声明。非常感谢您的意见! –

+0

澄清以上评论。我不需要为数组声明声明一个通用的简写函数,只是为了使代码片段可读。那么有更好的选择还是这种方式? –

+1

这是数组。 Kotlin不希望它们的特殊容量比其他收集类型有所不同。在JVM世界中,数组实际上具有统计上较低的使用率,并且当人们应该使用正常集合时,这些数据中的大部分是偶然的。所以它们被放置在与集合甚至字段相同的发现级别和语法级别。 –

10

至于stdlib的goest,这是尽可能短。然而,你可以定义一个辅助函数自己:

fun doubles(vararg values: Pair<Double, Double>) = values 
    .map { doubleArrayOf(it.first, it.second) } 
    .toTypedArray() 

用法:

fun main(args: Array<String>) { 
    val path = doubles(1.0 to 2.0, 1.0 to 3.0, 3.0 to 4.0, 8.0 to 9.0) 
} 

这不是最有效的解决方案,因为它涉及到拳击和一个临时数组和列表的配置,但如果你只有原型设计应该没问题。

编辑:

我也做了一个版本,你可以添加任意长度的数组:

inline fun doubles(block: DoubleArrayBuilder.() -> Unit) = DoubleArrayBuilder() 
     .apply(block) 
     .list.toTypedArray() 

class DoubleArrayBuilder { 
    val list = mutableListOf<DoubleArray>() 

    fun add(vararg doubles: Double) = list.add(doubles) 
} 

用法:

fun main(args: Array<String>) { 
    val path = doubles { 
     add(2.0, 3.0, 4.0) 
     add(2.0, 3.0, 4.0) 
     add(2.0, 3.0, 4.0) 
    } 
} 
+0

性能不是一个巨大的,但可读性。我在设置中看到的限制是它仅限于成对。 –

+1

我编辑了我的答案并添加了一个构建器样式的版本,您可以在其中添加任意长度的双数组。 –