-
Notifications
You must be signed in to change notification settings - Fork 6.4k
Expand file tree
/
Copy pathArrays.kt
More file actions
161 lines (137 loc) · 5.79 KB
/
Copy pathArrays.kt
File metadata and controls
161 lines (137 loc) · 5.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@file:kotlin.jvm.JvmMultifileClass
@file:kotlin.jvm.JvmName("ArraysKt")
package kotlin.collections
import kotlin.contracts.*
/**
* Returns a single list of all elements from all arrays in the given array.
* @sample samples.collections.Arrays.Transformations.flattenArray
*/
public fun <T> Array<out Array<out T>>.flatten(): List<T> {
val result = ArrayList<T>(sumOf { it.size })
for (element in this) {
result.addAll(element)
}
return result
}
/**
* Returns a pair of lists, where
* *first* list is built from the first values of each pair from this array,
* *second* list is built from the second values of each pair from this array.
* @sample samples.collections.Arrays.Transformations.unzipArray
*/
public fun <T, R> Array<out Pair<T, R>>.unzip(): Pair<List<T>, List<R>> {
val listT = ArrayList<T>(size)
val listR = ArrayList<R>(size)
for (pair in this) {
listT.add(pair.first)
listR.add(pair.second)
}
return listT to listR
}
/**
* Returns `true` if this nullable array is either null or empty.
* @sample samples.collections.Arrays.Usage.arrayIsNullOrEmpty
*/
@SinceKotlin("1.3")
@kotlin.internal.InlineOnly
public inline fun Array<*>?.isNullOrEmpty(): Boolean {
contract {
returns(false) implies (this@isNullOrEmpty != null)
}
return this == null || this.isEmpty()
}
/**
* Returns this array if it's not empty
* or the result of calling [defaultValue] function if the array is empty.
*
* @sample samples.collections.Arrays.Usage.arrayIfEmpty
*/
@SinceKotlin("1.3")
@kotlin.internal.InlineOnly
@Suppress("UPPER_BOUND_CANNOT_BE_ARRAY")
public inline fun <C, R> C.ifEmpty(defaultValue: () -> R): R where C : Array<*>, C : R =
if (isEmpty()) defaultValue() else this
@OptIn(ExperimentalUnsignedTypes::class)
@SinceKotlin("1.3")
@PublishedApi
@kotlin.jvm.JvmName("contentDeepEquals")
@kotlin.js.JsName("contentDeepEqualsImpl")
internal fun <T> Array<out T>?.contentDeepEqualsImpl(other: Array<out T>?): Boolean {
if (this === other) return true
if (this == null || other == null || this.size != other.size) return false
for (i in indices) {
val v1 = this[i]
val v2 = other[i]
if (v1 === v2) {
continue
} else if (v1 == null || v2 == null) {
return false
}
when {
v1 is Array<*> && v2 is Array<*> -> if (!v1.contentDeepEquals(v2)) return false
v1 is ByteArray && v2 is ByteArray -> if (!v1.contentEquals(v2)) return false
v1 is ShortArray && v2 is ShortArray -> if (!v1.contentEquals(v2)) return false
v1 is IntArray && v2 is IntArray -> if (!v1.contentEquals(v2)) return false
v1 is LongArray && v2 is LongArray -> if (!v1.contentEquals(v2)) return false
v1 is FloatArray && v2 is FloatArray -> if (!v1.contentEquals(v2)) return false
v1 is DoubleArray && v2 is DoubleArray -> if (!v1.contentEquals(v2)) return false
v1 is CharArray && v2 is CharArray -> if (!v1.contentEquals(v2)) return false
v1 is BooleanArray && v2 is BooleanArray -> if (!v1.contentEquals(v2)) return false
v1 is UByteArray && v2 is UByteArray -> if (!v1.contentEquals(v2)) return false
v1 is UShortArray && v2 is UShortArray -> if (!v1.contentEquals(v2)) return false
v1 is UIntArray && v2 is UIntArray -> if (!v1.contentEquals(v2)) return false
v1 is ULongArray && v2 is ULongArray -> if (!v1.contentEquals(v2)) return false
else -> if (v1 != v2) return false
}
}
return true
}
@SinceKotlin("1.3")
@PublishedApi
@kotlin.jvm.JvmName("contentDeepToString")
@kotlin.js.JsName("contentDeepToStringImpl")
internal fun <T> Array<out T>?.contentDeepToStringImpl(): String {
if (this == null) return "null"
val length = size.coerceAtMost((Int.MAX_VALUE - 2) / 5) * 5 + 2 // in order not to overflow Int.MAX_VALUE
return buildString(length) {
contentDeepToStringInternal(this, mutableListOf())
}
}
@OptIn(ExperimentalUnsignedTypes::class)
private fun <T> Array<out T>.contentDeepToStringInternal(result: StringBuilder, processed: MutableList<Array<*>>) {
if (this in processed) {
result.append("[...]")
return
}
processed.add(this)
result.append('[')
for (i in indices) {
if (i != 0) {
result.append(", ")
}
val element = this[i]
when (element) {
null -> result.append("null")
is Array<*> -> element.contentDeepToStringInternal(result, processed)
is ByteArray -> result.append(element.contentToString())
is ShortArray -> result.append(element.contentToString())
is IntArray -> result.append(element.contentToString())
is LongArray -> result.append(element.contentToString())
is FloatArray -> result.append(element.contentToString())
is DoubleArray -> result.append(element.contentToString())
is CharArray -> result.append(element.contentToString())
is BooleanArray -> result.append(element.contentToString())
is UByteArray -> result.append(element.contentToString())
is UShortArray -> result.append(element.contentToString())
is UIntArray -> result.append(element.contentToString())
is ULongArray -> result.append(element.contentToString())
else -> result.append(element.toString())
}
}
result.append(']')
processed.removeAt(processed.lastIndex)
}