What is the Kotlin way of printing IntArray contents? - kotlin

What is the Kotlin way of printing IntArray contents?
class Solution {
fun plusOne(digits: IntArray): IntArray {
println(digits.toString()) // does not work
println(Arrays.toString(digits)) // does work but its java way of doing
for(i in 0 until digits.size) {
...
}
return digits
}
}
Is there any kotlin method which works similar to Arrays.toString() ? I just want to see the content for debugging purpose.

There are multiple ways, depending on your requirement, you can use any. Note that you don't have to convert it to List just to print, unless you need it for other use cases.
println(arr.contentToString())
//this one prints number on each line
arr.forEach(::println) // same as arr.forEach{println(it)}
You can also use Arrays.toString but contentToString() is convenient, and it internally calls Arrays.toString

After doing a bit more research, I wanted to add joinToString() to above awesome answers :
val numbers = intArrayOf(1, 2, 3, 4, 5, 6)
println(numbers.joinToString())
This will print below output :
1, 2, 3, 4, 5, 6
This also allows you add prefix, suffix of your choice as below :
println(numbers.joinToString(prefix = "{", postfix = "}"))
This would output :
{1, 2, 3, 4, 5, 6}

You can use the contentToString function available for all types of Array
val digits = intArrayOf(1,2,3,4)
val javaToString = Arrays.toString(digits).also(::println) // [1, 2, 3, 4]
val kotlinToString = digits.contentToString().also(::println) // [1, 2, 3, 4]
println(javaToString == kotlinToString) // true
Here is a working example https://pl.kotl.in/dUu_aioq0

There are many ways to accomplish it.
One way would be to first build the output string using fold and then print it inside an also function:
val digits = intArrayOf(1,2,3,4,5,6,7)
digits.fold("[") { output, item -> "$output $item" }.also { println("$it ]") }
This would output:
[ 1 2 3 4 5 6 7 ]

Try to convert to list
fun main() {
val digits: IntArray = IntArray(10)
println(digits.toList()) // or digits.asList()
}
Output:
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

Related

How do I chain operators over lists in rust? Looking for equivalent to kotlin code

I have the following code in kotlin and I'm trying to find a rust equivalent, but don't understand the chaining mechanism in rust to convert.
val windowSize = 2
val result = listOf(1, 2, 3, 4, 5, 6)
.windowed(windowSize, 1) ; [[1,2], [2,3], [3,4], [4,5], [5,6]]
.map { it.sum() } ; [ 3, 5, 7, 9, 11]
.windowed(2, 1) ; [[3,5], [5,7], [7,9], [9,11] ]
.count { it[0] < it[1] } ; 4
;; result = 4, as there are 4 sequences that have first number less than 2nd,
;; when considering a sliding window over the original data of 2 items at a time.
It just takes a list of integers, splits them into pairs (but the windowSize will be a function parameter), sums those groups, splits the sums into pairs again, and finds where each second element is bigger than the previous, so finding increasing values over moving windows.
I'm converting this to the rust equivalent, but struggling to understand how to chain operations together.
What I've got so far is:
let input = [1, 2, 3, 4, 5, 6];
input.windows(2)
.map(|es| es.iter().sum())
// what goes here to do the next windows(2) operation?
.for_each(|x: u32| println!("{}", x));
I can "for_each" over the map to do things on the iteration, but I can't split it with another "windows()", or don't know the magic to make that possible. IntelliJ is showing me the return type from map is impl Iterator<Item=?>
Can anyone enlighten me please? I am an absolute beginner on rust, so this is undoubtedly to do with my understanding of the language as a whole.
The Itertools crate provides a reasonably convenient way to do this with the tuple_windows method.
use itertools::Itertools;
fn main() {
let input = [1i32, 2, 3, 4, 5, 6];
let output: usize = input
.windows(2)
.map(|es| es.iter().sum::<i32>())
.tuple_windows()
.filter(|(a, b)| a < b)
.count();
println!("{}", output);
}
Playground
The standard library does not have a way to do this without collecting the iterator first, which requires two passes through the data.
It is a bit convoluted to chain everything. You need to collect into a vec so you can access windows again. Then you can flat_map the windows to array references (taken from this other answer) to complete what you want to do:
fn main() {
let input = [1usize, 2, 3, 4, 5, 6];
let res = input
.windows(2)
.map(|es| es.iter().sum::<usize>())
.collect::<Vec<_>>()
.windows(2)
.flat_map(<[usize; 2]>::try_from)
.filter(|[a, b]| a < b)
.count();
println!("{}", res);
}
Playground
Note: Nightly feature array_windows that use const generic allow to remove the .flat_map(<&[usize; 2]>::try_from) call
As stated in #Aiden4's answer, the best solution is to use itertools::tuple_windows. It is however possible using just the standard library and without collecting to an intermediate vector using Iterator::scan:
fn main() {
let input = [1i32, 2, 3, 4, 5, 6];
let output: usize = input
.windows(2)
.map(|es| es.iter().sum())
.scan(0, |prev, cur| {
let res = (*prev, cur);
*prev = cur;
Some(res)
})
.skip(1)
.filter(|(a, b)| a < b)
.count();
println!("{}", output);
}
Playground
Using std and stable only:
fn main() {
let input = [1i32, 2, 3, 4, 5, 6];
let mut iter = input.windows(2).map(|es| es.iter().sum::<i32>());
let n = if let Some(mut prev) = iter.next() {
iter.map(|i| {
let ret = (prev, i);
prev = i;
ret
})
.filter(|(a, b)| a < b)
.count()
} else {
0
};
println!("{}", n);
}
This should be very fast.

How to put range of ints instead writing them one by one kotlin listOf

For example we have such array:
val listArr = listOf(1,2,3,4,5,6,7)
and finally we receive:
1,2,3,4,5,6,7
maybe it is possible to write something like that:
val listArr = listOf(1..7)
and receive similar result. Or it is impossible right now?
You can use the IntRange.toList() function:
val list = (1..7).toList()
Ranges are automatically converted to lists when concatenating:
val combined = (1..6) + 12 + (34..37)
// [1, 2, 3, 4, 5, 6, 12, 34, 35, 36, 37]
RobCo's answer is correct and answers the question asked.
About the followup question you asked in the comment to his answer:
how we can use such solution in another list for example 1,2,3,4,5,6,12,34,35,36,37
You could write a new function that accepts ranges:
fun customListOf(vararg ranges: IntRange) = ranges.flatMap { it.toList() }
Then use it like this:
fun main() {
val list = customListOf(1..6, 12..12, 34..37)
println(list)
}
Output:
[1, 2, 3, 4, 5, 6, 12, 34, 35, 36, 37]
However, you need to pass a range even for a single value like 12..12 above.
If you wanted to be hacky, you could write a function that accepts a vararg range: Any, and use reflection to check the type at runtime. That would allow you to mix ranges and ints in the same call:
fun hackyCustomListOf(vararg rangeOrInt: Any) = rangeOrInt.flatMap {
when (it) {
is IntRange -> it.toList()
is Int -> listOf(it)
else -> throw IllegalArgumentException("Expected an IntRange or an Int, got ${it::class}")
}
}
Usage:
fun main() {
val list1 = hackyCustomListOf(1, 5, 12..15, 25, 99..102)
println(list1)
val list2 = hackyCustomListOf(1..3, "boom", 5.0)
println(list2)
}
Output:
[1, 5, 12, 13, 14, 15, 25, 99, 100, 101, 102]
Exception in thread "main" java.lang.IllegalArgumentException: Expected an IntRange or an Int, got class kotlin.String
at TestKt.hackyCustomListOf(test.kt:7)
at TestKt.main(test.kt:14)
at TestKt.main(test.kt)
This removes compile-time checks on the argument, so I don't think it's a good idea. Fun exercise, though.

How to create proxy list that has every second element of original list?

I need a wrapper list that reflects all changes of an original list like subList() but contains only every second element.
I tried:
fun getWrapperList (original_list: List<T>): List<T> =
IntRange(0, original_list.size.div(2)).map { original_list[it * 2 + 1] }
But it creates a new list that doesn't reflects changes.
I don't think there's anything in the standard library for this, as it's not a common requirement.  (The only times I can remember wanting to access alternate elements, I should have refactored the code to a list of sub-objects instead…)
But you can create your own easily enough.
The simplest way is probably by extending AbstractList, e.g.:
class AlternateView<T>(val sourceList: List<T>): AbstractList<T>() {
override val size get() = (sourceList.size + 1) / 2
override fun get(index: Int) = sourceList[index * 2]
}
(That gives the first, third, fifth… items; I'm sure you can see how to tweak it if you want the others.  Or make that a constructor param and support both.)
That works as required, with changes to the original list reflected in the view:
val list = mutableListOf(1, 2, 3, 4, 5, 6)
val view = AlternateView(list)
println("list=$list, view=$view") // list=[1, 2, 3, 4, 5, 6], view=[1, 3, 5]
list[0] = 7
list.removeAt(1)
list.add(4, 8)
println("list=$list, view=$view") // list=[7, 3, 4, 5, 8, 6], view=[7, 4, 8]
If performance matters, you should probably look at overriding more of the AbstractList methods, or even implementing List directly.  But that could be a lot of work, and this simple version should suffice in many cases.
You should be able to do something like following (using computed property)
class SomeClass {
val originalList = mutableListOf(1, 2, 3, 4, 5, 6)
val derivedList: List<Int>
get() = originalList.filterIndexed { index, i -> index % 2 == 0 }
}
fun main() {
val someClass = SomeClass()
println(someClass.originalList)
println(someClass.derivedList)
someClass.originalList.add(7)
println(someClass.derivedList)
}
Above generates output of
[1, 2, 3, 4, 5, 6]
[1, 3, 5]
[1, 3, 5, 7]

How to debug Kotlin sequences / collections

Take the following one-liner, which can be expressed as a series of operations on a collection or a sequence:
val nums = (10 downTo 1)
// .asSequence() if we want this to be a sequence
.filter { it % 2 == 0 }
.map { it * it }
.sorted()
// .asList() if declaring it a sequence
println(nums) // [4, 16, 36, 64, 100]
Let's say I want to see the elements at each step, they would be (from deduction):
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
[10, 8, 6, 4, 2]
[100, 64, 36, 16, 4]
[4, 16, 36, 64, 100]
Unfortunately, there's no good way to either debug this with a debugger or log these values for later inspection. With good functional programming constructs, entire methods can be rewritten as single statements like this but there seems to be no good way to inspect intermediate states, even counts (10, 5, 5, 5 here).
What's the best way to debug these?
You can log the intermediate values (lists) with
fun <T> T.log(): T { println(this); this }
//USAGE:
val nums = (10 downTo 1)
.filter { it % 2 == 0 }.log()
.map { it * it }.log()
.sorted().log()
This will work as desired since in your example you work with collections, not sequences. For lazy Sequence you need:
// coming in 1.1
public fun <T> Sequence<T>.onEach(action: (T) -> Unit): Sequence<T> {
return map {
action(it)
it
}
}
fun <T> Sequence<T>.log() = onEach {print(it)}
//USAGE:
val nums = (10 downTo 1).asSequance()
.filter { it % 2 == 0 }
.map { it * it }.log()
.sorted()
.toList()
In latest Intellij Idea when adding a breakpoint you have an option to set it to not inspect whole expression but only a Lambda body.
Then in the debug itself you can see what is happening inside of your Lambda.
But this is not the only way. You can also use Run to cursor (Alt + F9).
I think the current correct answer is that you want the Kotlin Sequence Debugger plugin, which lets you use IntelliJ's lovely Java stream debugger with Kotlin sequences.
Note that (unless I'm doing something wrong) it doesn't appear to work with collections, so you will have to convert the collection to a sequence in order to debug it. Easy enough using Iterable.asSequence, and a small price to pay -- you can always revert that change once you are done debugging.
you may use the also inline function to log, print at any sequence stage as explained by Andrey Breslav at Google I/O '18
(1..10)
.filter { it % 2 == 0 }
.also { e -> println(e) /* do your debug or print here */ }
.map { it * 2 }
.toList()

Kotlin, how to test (int)array

I'd like to find a nice and concise way to test intarray
at first I tried
mFaces[0].mIndices shouldBe intArrayOf(0, 1, 2)
where mIndices is
var mIndices: IntArray = IntArray(0)
but fails. Intellij also suggests me to override equals() with Arrays
Then I wanted to try something like this
mFaces[0].mIndices.all { it. == index } shouldBe true
but it looks like there is no way to retrieve the index of it inside all{..} or is this
var p = 0
mFaces[0].mIndices.all { it == p++ } shouldBe true
the only possibility?
In Java (Kotlin) arrays are compared by reference, not by content. That means that intArrayOf(1, 2, 3) != intArrayOf(1, 2, 3).
To compare content of arrays you have 2 options:
Use deep comparison:
Arrays.deepequals(mFaces[0].mIndices, intArrayOf(0, 1, 2))
Use lists:
mFaces[0].mIndices.toList() == listOf(0, 1, 2)