Problem overview
The method 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 method returns a new array of full names, each a first name, one space, and a last name, in the original order.
With firstNames = ["John", "Andy", "Mary"] and lastNames = ["Doe", "Smith", "Johnson"], the result is ["John Doe", "Andy Smith", "Mary Johnson"].
Approach
Two arrays that are related by position can't be walked with a plain for name in firstNames loop, because that loop hands you the first names and gives no way to reach the last name next to each one. The fix is to loop over the positions instead. For every index i, you can read firstNames[i] and lastNames[i] together, join them, and store the result.
The results go into a new array, so the input arrays stay unchanged.
Step by step
- Create the result array. It starts empty and grows as names are added, so it must be declared with
var.[String]()creates an empty array of strings. - Loop over the indices of
firstNames. The range0..<firstNames.countyields0, 1, 2, ...up to the last valid position. The upper bound is excluded, which is what you want, because the last valid index iscount - 1. - Build one full name. Join
firstNames[i], a single space" ", andlastNames[i]with+. The space is a separate string between the two names. - Append it.
names.append(name)adds the new string at the end of the result, which keeps the original order. - Return the array after the loop. The
returngoes outside the loop. Placed inside, it would end the method after the first name.
The solution in Swift
class Solution {
func getFullNames(_ firstNames: [String], _ lastNames: [String]) -> [String] {
var names = [String]()
for i in 0..<firstNames.count {
let name = firstNames[i] + " " + lastNames[i]
names.append(name)
}
return names
}
}
Swift details worth knowing:
letandvar.nameis aletbecause it is set once per iteration.namesis avarbecauseappendchanges it. Callingappendon aletarray is a compile error.- The underscores in the signature.
_ firstNamesmeans the caller doesn't write an argument label, so the call isgetFullNames(first, last)rather thangetFullNames(firstNames: first, lastNames: last). - String interpolation is an alternative.
"\(firstNames[i]) \(lastNames[i])"builds the same string. - Arrays are value types. The method works on its own copies, so the caller's arrays are never modified, and the returned array is a separate value.
- Out-of-range indexing traps. Reading
lastNames[i]past the end stops the program with an error. The lesson's inputs have equal lengths, so that doesn't happen here.
Complexity
Time: O(n), where n is the number of names. The loop runs n times and each iteration joins two strings and appends to the array. Appending is amortized constant time, and each join costs time proportional to the length of the two names.
Space: O(n) for the result array, which holds one string per name.
Edge cases and common mistakes
- Empty input. Two empty arrays give an empty result, because the range
0..<0has no values. - Single name.
["A"]and["B"]give["A B"]. - Forgetting the space.
firstNames[i] + lastNames[i]gives"JohnDoe". - Using a closed range.
0...firstNames.countincludescount, one past the last index, and crashes. - Returning inside the loop. The method then returns after one name.
- Declaring
nameswithlet. The compiler rejects theappendcall.
Testing
["John", "Andy", "Mary"]and["Doe", "Smith", "Johnson"]give["John Doe", "Andy Smith", "Mary Johnson"].["A"]and["B"]give["A B"].[]and[]give[].
