I want to be able to remove all duplicates if they are in a consecutive position in an array. For example, I have this array:
[1,2,2,3,2,5,1,1,6,1]
And now, I want to remove all the duplicates if they are in the same position. And in the end, after removing the elements, the final array will look like this:
[1,2,3,2,5,1,6,1]
And clearly, we can see that we are removing it if it is in its next position.
Note: I don't want this only with integers. I want to it work with all objects. Also, I don't want to remove all the duplicates. Remove them only if it is in the following position.
So, how can I achieve this with java or kotlin.
CodePudding user response:
val list = listOf(1, 2, 2, 3, 2, 5, 1, 1, 6, 1)
val result = list.filterIndexed { index, i ->
if (index > 0) i != list[index - 1] else true
// or: if (index < list.size - 1) i != list[index 1] else true
}
println(result)
Edit, for scalar types and data classes:
fun <T : Any> List<T>.filterConsecutiveDuplicates() =
filterIndexed { index, i -> if (index < size - 1) i != this[index 1] else true }
val list = listOf(1, 2, 2, 3, 2, 5, 1, 1, 6, 1)
val list2 = list.filterConsecutiveDuplicates()
data class O(val name: String)
val objects = listOf(O("A"), O("A"), O("B"), O("A"), O("B"), O("C"), O("C"), O("A"))
val objects2 = objects.filterConsecutiveDuplicates()
CodePudding user response:
If you want a Java method to do this:
I don't know of any method in Java that you can conveniently use to do this. Just implement the logic yourself. Try something like what's shown below:
int[] a = ... // whatever initial array value
List<Integer> b = new ArrayList<Integer>(); // final array after processing
b.add(a[0]);
for(int i = 1; i < a.length; i) if(a[i] != a[i-1]) b.add(a[i]);
b
Should store the contents of what you want.
CodePudding user response:
val list = listOf(1,2,2,3,2,5,1,1,6,1)
// if list is empty then result is empty list
val mutableList = mutableListOf(list.first())
list.forEach {
if (it != mutableList.last()) {
mutableList.add(it)
}
}
println(mutableList.joinToString { it.toString() })
CodePudding user response:
You already have a java version, this would be the Kotlin one. We can take advantage of Kotlin's zipWithNext to make it simpler, but to note is that we are creating a new list.
fun main() {
val list = listOf(1, 2, 2, 3, 2, 5, 1, 1, 6, 1)
val result = list.removeConsecutiveDuplicates()
println(result)
}
fun <T> Collection<T>.removeConsecutiveDuplicates(): MutableList<T> {
val result = mutableListOf<T>()
this.zipWithNext { a, b -> if (a != b) result = a }
return result
}
The print result is [1, 2, 3, 2, 5, 1, 6]
.
As DrPhill suggested, you can do it without an explicit second list, he did it with mapNotNull
, but I would personally prefer it with .filter
fun <T> Collection<T>.removeConsecutiveDuplicates(): List<T> {
return this.zipWithNext().filter { (a, b) -> a != b }.map { it.first }
}
CodePudding user response:
Based on Alex.T
fun <T> Collection<T>.removeConsecutiveDuplicates(): MutableList<T> {
return this.zipWithNext().mapNotNull {a, b -> if (a != b) a else null }
}
I now prefer Alex.T's modification of my suggestion - much clearer. Best so far (imho)