Start learning free

LESSON 149 OF 348 · LOOPING OVER ARRAY INDICES

Get Full Names in Kotlin: Pairing Two Arrays by Index

Practice Read the full explanation

Given two arrays of strings named firstNames and lastNames, return an array containing the full names (separated by one space)

Example:

Input:   firstNames = ["John","Andy","Mary"]
         lastNames = ["Doe","Smith","Johnson"]

Output:  ["John Doe", "Andy Smith", "Mary Johnson"]
STEP 1 OF 5
    Ctrl + Enter to check

    KOTLIN · LOOPING OVER ARRAY INDICES

    Get Full Names in Kotlin, explained

    Problem overview

    The function getFullNames receives two arrays of strings, firstNames and lastNames. The name at position i in one array belongs with the name at position i in the other. The function returns a List<String> holding each full name, with one space between the first and the last name, in the original order.

    For firstNames = ["John", "Andy", "Mary"] and lastNames = ["Doe", "Smith", "Johnson"], the result is ["John Doe", "Andy Smith", "Mary Johnson"]. "John" and "Doe" share index 0, "Andy" and "Smith" share index 1, and so on.

    Approach

    Because the two arrays are related only by position, you can't loop over the names themselves: for (first in firstNames) would give you a first name with no way to find its last name. You need the index. Loop over every valid index of firstNames, and at each index read one element from each array, join them, and collect the result.

    Each index is visited exactly once, so the work grows in step with the number of names. There is no need to compare names with each other or to search for anything.

    Step by step

    1. Create the collector. The answer is built one name at a time, so start with an empty list that can grow. listOf creates a read-only list, which has no add; mutableListOf<String>() creates one you can add to. The variable can be a val, because it always refers to the same list while the list's contents change.
    2. Loop over the indices. firstNames.indices is the range 0 to size - 1. With for (i in firstNames.indices), the variable i is a position you can use in both arrays.
    3. Build one full name. Join firstNames[i], a single space and lastNames[i] with +. The space is a separate string between the two names.
    4. Add it to the list. names.add(name) appends to the end, which keeps the original order.
    5. Return after the loop. Only when every index has been handled does names hold the complete answer.

    The solution in Kotlin

    class Solution {
        fun getFullNames(firstNames: Array<String>, lastNames: Array<String>): List<String> {
            val names = mutableListOf<String>()
            for (i in firstNames.indices) {
                val name = firstNames[i] + " " + lastNames[i]
                names.add(name)
            }
            return names
        }
    }
    

    Some details of this code:

    • Parameter types. The inputs are Array<String>, a fixed-size array of strings. The return type is List<String>, which is read-only for the caller, even though inside the function the object is a MutableList. Returning it as List is allowed because a mutable list is also a list.
    • String joining. + on strings builds a new string; the originals are unchanged. A string template does the same job: "${firstNames[i]} ${lastNames[i]}" produces the identical text.
    • The loop variable. i is a val inside the loop, and that is fine here, since the loop only reads the arrays and never assigns to i.
    • A shorter form. firstNames.indices.map { "${firstNames[it]} ${lastNames[it]}" } returns the same list. The explicit loop is the form the lesson's steps follow.

    Complexity

    Time: O(n), where n is the number of names. The loop runs n times, and each pass does a fixed amount of work: two array reads, one string join and one append. Appending to a MutableList takes constant time on average. Strictly speaking, each join copies the characters of both names, so the cost also depends on name length, but names are short and the loop count dominates.

    Space: O(n) for the result list, which holds one string per name. Nothing else grows with the input.

    Edge cases and common mistakes

    • Empty arrays. The range indices is empty, the loop body never runs, and the function returns an empty list.
    • Arrays of different sizes. The code loops over firstNames.indices. If lastNames is shorter, lastNames[i] throws ArrayIndexOutOfBoundsException at the first missing index. If it is longer, the extra last names are ignored. The lesson's examples use arrays of equal length.
    • Forgetting the space. firstNames[i] + lastNames[i] gives JohnDoe.
    • Using a read-only list. With val names = listOf<String>() the call names.add(name) doesn't compile.
    • Returning inside the loop. Putting return names before the closing brace of the loop ends the function after the first name.

    Testing

    Try these inputs in the editor above:

    • ["John", "Andy", "Mary"] with ["Doe", "Smith", "Johnson"] returns [John Doe, Andy Smith, Mary Johnson].
    • Two empty arrays return [].
    • ["A"] with ["C"] returns [A C].
    Keep going with KotlinAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free