Home > Back-end >  How to Remove all duplicates if it is a consecutive position?
How to Remove all duplicates if it is a consecutive position?

Time:06-06

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 or .

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)

  • Related