Question

How to Remove Duplicate Strings from an Array in Kotlin

kotlinalgorithm

Question

How can I remove duplicate values from an Array<String?> in Kotlin?

For example, given an array of nullable strings, I want to create a result that keeps only one copy of each value, including handling null correctly when it appears.

Short Answer

By the end of this page, you will understand how to remove duplicate values from a Kotlin array, especially an Array<String?>. You will learn the most common Kotlin approaches such as distinct(), converting to a Set, and when to choose each option. You will also see how null values behave and how order is affected.

Concept

In Kotlin, removing duplicates means keeping only unique values from a collection.

For an Array<String?>, duplicates can include:

  • repeated strings like "apple"
  • repeated null values

Kotlin provides collection functions that make this simple. The most beginner-friendly option is distinct().

val items = arrayOf("apple", "banana", "apple", null, null)
val unique = items.distinct()
println(unique) // [apple, banana, null]

Why this works

distinct() returns a new list containing only the first occurrence of each value. If the same value appears again later, Kotlin skips it.

This matters because duplicate removal is common in real programs:

  • cleaning user input
  • preparing API data
  • filtering repeated tags or categories
  • avoiding repeated processing

Important detail: arrays vs lists

In Kotlin, Array is not the same as List.

  • Array<String?> is a fixed-size array
  • distinct() returns a List<String?>

So if you want the final result to still be an array, convert it back:

val uniqueArray = items.distinct().toTypedArray()

How null is handled

Kotlin treats null like any other value for duplicate checking. That means:

  • one null is kept
  • repeated null values are removed

Example:

val items = arrayOf("a", null, "a", null)
val unique = items.distinct()
println(unique) // [a, null]

Order preservation

distinct() preserves the original order of first appearances.

val items = arrayOf("b", "a", "b", "c")
val unique = items.distinct()
println(unique) // [b, a, c]

This is often useful because you usually want unique values without scrambling the original order.

Mental Model

Think of duplicate removal like checking people into an event.

  • You have a list of names arriving in order.
  • A staff member keeps a record of who has already entered.
  • If a name appears for the first time, it is allowed in.
  • If the same name appears again, it is ignored.
  • null is like a guest with no name tag: the first one is still recorded, but repeated unnamed entries are ignored.

So Kotlin's duplicate-removal process is basically:

  1. read each item from left to right
  2. remember what has already been seen
  3. keep only the first appearance of each value
Take Quiz

Syntax and Examples

The most common ways to remove duplicates from an Array<String?> in Kotlin are below.

1. Use distinct()

val items = arrayOf("apple", "banana", "apple", null, "banana", null)
val unique = items.distinct()

println(unique) // [apple, banana, null]
  • distinct() returns a List<String?>
  • it keeps the first occurrence of each value
  • it preserves order

2. Convert back to an array

If you need an array as the result:

val items = arrayOf("apple", "banana", "apple", null)
val uniqueArray = items.distinct().toTypedArray()

println(uniqueArray.contentToString()) // [apple, banana, null]

3. Use toSet()

val items = arrayOf("apple", "banana", "apple", null)
val uniqueSet = items.toSet()

println(uniqueSet) // [apple, banana, null]

This also removes duplicates, but the result type is a Set<String?>, not an array or list.

4. Remove duplicates and remove nulls

If you want only unique non-null strings:

val items = arrayOf("apple", null, "apple", "banana", null)
val uniqueNonNull = items.filterNotNull().distinct()

println(uniqueNonNull) // [apple, banana]

Beginner-friendly example

fun main() {
    val names: Array<String?> = arrayOf("Ali", "Mina", "Ali", null, "Sara", null)

    val uniqueNames = names.distinct()

    println(uniqueNames)
}

What this prints

[Ali, Mina, null, Sara]

Why

  • Ali appears twice, so only the first one is kept
  • null appears twice, so only one null is kept
  • order stays the same as the original array

Step by Step Execution

Consider this example:

val items = arrayOf("cat", null, "dog", "cat", null, "bird")
val unique = items.distinct()
println(unique)

Let's trace it.

Initial array

["cat", null, "dog", "cat", null, "bird"]

Step 1: read "cat"

  • not seen before
  • keep it

Current result:

["cat"]

Step 2: read null

  • not seen before
  • keep it

Current result:

["cat", null]

Step 3: read "dog"

  • not seen before
  • keep it

Current result:

["cat", null, "dog"]

Step 4: read "cat" again

  • already seen
  • skip it

Current result stays:

["cat", null, "dog"]

Step 5: read null again

  • already seen
  • skip it

Current result stays:

["cat", null, "dog"]

Step 6: read "bird"

  • not seen before
  • keep it

Final result:

["cat", null, "dog", "bird"]

Printed output

[cat, null, dog, bird]

Real World Use Cases

Removing duplicates from arrays and collections is common in many Kotlin applications.

User input cleanup

A form may collect repeated tags or categories.

val tags = arrayOf("kotlin", "android", "kotlin", null)
val uniqueTags = tags.distinct()

API response cleanup

Sometimes API data contains repeated values.

val cities = arrayOf("Paris", "Tokyo", "Paris")
val uniqueCities = cities.distinct()

Search history

You may want to show each search term only once.

val searches = arrayOf("phone", "laptop", "phone")
val uniqueSearches = searches.distinct()

Data import scripts

CSV or database imports often need duplicate filtering before saving.

val emails = arrayOf("a@example.com", "b@example.com", "a@example.com")
val uniqueEmails = emails.distinct()

UI dropdown options

A dropdown should not show the same option multiple times.

val categories = arrayOf("Books", "Games", "Books")
val uniqueCategories = categories.distinct()
Take Quiz

Real Codebase Usage

In real Kotlin codebases, developers usually choose a duplicate-removal approach based on the result type they need.

Common pattern: distinct() for readable code

val uniqueNames = names.distinct()

This is the most readable and idiomatic choice when you want a list.

When an array is still required

val uniqueNamesArray = names.distinct().toTypedArray()

This is common when calling older APIs or code that specifically expects Array<String?>.

Validation before duplicate removal

Developers often clean data first, then deduplicate it.

val cleaned = names
    .filterNotNull()
    .map { it.trim() }
    .filter { it.isNotEmpty() }
    .distinct()

This pattern is common when processing form fields or imported text.

Early data normalization

In real projects, duplicate removal is often part of a pipeline:

val result = rawValues
    .filterNotNull()
    .map { it.lowercase() }
    .distinct()

This avoids treating "Kotlin" and "kotlin" as different if the business rule says they should match.

Set-based usage

If the codebase needs fast membership checks later, developers may keep the data as a set.

val allowedNames = names.toSet()
if ("Ali" in allowedNames) {
    println("Found")
}

This is useful when uniqueness is more important than array/list behavior.

Common Mistakes

Here are common beginner mistakes when removing duplicates in Kotlin.

Mistake 1: Expecting distinct() to return an array

val items: Array<String?> = arrayOf("a", "a", null)
val unique: Array<String?> = items.distinct() // Error

Why it fails

distinct() returns a List<String?>, not an Array<String?>.

Fix

val unique: Array<String?> = items.distinct().toTypedArray()

Mistake 2: Forgetting that null is kept once

Some beginners expect all null values to disappear automatically.

val items = arrayOf("a", null, "a", null)
println(items.distinct()) // [a, null]

Fix

If you want to remove null completely:

val uniqueNonNull = items.filterNotNull().distinct()

Mistake 3: Using toSet() without noticing the type change

val items = arrayOf("a", "b", "a")
val unique = items.toSet()

This works, but unique is a Set<String?>, not a list or array.

Fix

Choose the method based on the result type you need.

Mistake 4: Assuming case differences are duplicates

val items = arrayOf("Kotlin", "kotlin")
println(items.distinct()) // [Kotlin, kotlin]

These are different strings.

Fix

Normalize first if needed:

val unique = items.map { it?.lowercase() }.distinct()

Mistake 5: Assuming duplicates are removed in place

val items = arrayOf("a", "a", "b")
items.distinct()
println(items.contentToString()) // [a, a, b]

Why

distinct() returns a new collection. It does not change the original array.

Fix

Store the result:

val unique = items.distinct()

Comparisons

Here is how the main options compare.

ApproachReturnsPreserves first-seen orderKeeps one nullBest for
distinct()List<String?>YesYesIdiomatic duplicate removal
distinct().toTypedArray()Array<String?>YesYesWhen you still need an array
toSet()Set<String?>Typically yes for Kotlin's default set creation, but use it mainly for uniqueness rather than sequence behaviorYesUnique membership checks
filterNotNull().distinct()List<String>YesNoUnique values with no nulls

distinct() vs toSet()

val items = arrayOf("a", "b", "a", null)

val asList = items.distinct()
val asSet = items.toSet()
  • Use distinct() when you want a clear, ordered result for display or further list processing.
  • Use toSet() when you want uniqueness as a property and may perform membership checks.

Array vs List in Kotlin

TypeSizeCommon use
Array<String?>Fixed sizeInterop, specific APIs, indexed storage
List<String?>Read-only view of valuesMost Kotlin collection operations

In Kotlin, many helpful operations return lists, so converting from arrays to lists and back is normal.

Take Quiz

Cheat Sheet

// Original array
val items: Array<String?> = arrayOf("a", "b", "a", null, null)

// Remove duplicates -> List<String?>
val uniqueList = items.distinct()

// Remove duplicates -> Array<String?>
val uniqueArray = items.distinct().toTypedArray()

// Remove duplicates -> Set<String?>
val uniqueSet = items.toSet()

// Remove nulls first, then duplicates -> List<String>
val uniqueNonNull = items.filterNotNull().distinct()

// Normalize case, then remove duplicates
val uniqueLower = items.map { it?.lowercase() }.distinct()

Quick rules

  • distinct() returns a new List
  • it keeps the first occurrence of each value
  • it preserves order
  • repeated null values become a single null
  • use toTypedArray() if you need an array again
  • use filterNotNull() if null should be removed entirely

Common patterns

items.distinct()
items.distinct().toTypedArray()
items.filterNotNull().distinct()
items.map { it?.trim() }.distinct()

Watch out for

  • "A" and "a" are different unless normalized
  • original array is not modified
  • toSet() changes the collection type

FAQ

How do I remove duplicates from an array in Kotlin?

Use distinct().

val unique = items.distinct()

If you need an array result, use:

val uniqueArray = items.distinct().toTypedArray()

Does Kotlin distinct() work with null values?

Yes. It treats null as a normal value and keeps only one null if multiple are present.

Does distinct() preserve order in Kotlin?

Yes. It keeps values in the order of their first appearance.

What is the difference between distinct() and toSet() in Kotlin?

distinct() returns a List, while toSet() returns a Set. Both remove duplicates, but they produce different collection types.

How do I remove duplicates and also remove null values?

Use filterNotNull() before distinct().

val result = items.filterNotNull().distinct()

Can I remove duplicates directly inside the original array?

Not in place with distinct(). Arrays have fixed size, so you usually create a new list or a new array.

Why does distinct() not return an array?

Because Kotlin's collection functions commonly return lists for flexibility and consistency. Convert back with toTypedArray() if needed.

Take Quiz

Mini Project

Description

Create a small Kotlin program that cleans a list of imported usernames. The imported data may contain repeated names and repeated null values. Your program should produce a clean result with unique values while preserving the original order. This demonstrates real-world collection cleanup on nullable string arrays.

Goal

Build a Kotlin program that removes duplicate values from an Array<String?> and prints both the original and cleaned results.

Requirements

  • Create an Array<String?> with duplicate strings and duplicate null values.
  • Print the original array.
  • Remove duplicates while preserving order.
  • Convert the result back to an array.
  • Print the cleaned array.
Take Quiz

Keep learning

Related questions

View more