While preparing for a technical coding interview, and practising LeetCode questions, I created this *cheatsheet*.

As you know, coding interview requires interviewee to manipulate collection types (array, dictionary, set) **expertly** to solve mathematic puzzles.

## Loop array

```
for value in array
for index in array.indices
for (index, value) in array.enumerated()
```

## Loop array with range

```
for i in 0..<array.count // Traditional loop with indices
for v in array[2...] // Skip the first 2 elements
for v in array[..<(array.count-2)] // Skip the last 2 elements
for v in array.prefix(3) // The first 3
for v in array.suffix(3) // The last 3
```

## Loop dictionary

```
for (key, value) in dictionary
```

## Check if dictionary has key

```
dictionary.keys.contains("k")
```

```
// Alternative, if the value type is _never_ `Optional`
if dictionary["k"] == nil // "k" is not in keys
```

## Special sequences

```
let tenOnes = repeatElement(1, count: 10) // Array(tenOnes)
stride(from: 0, to: 60, by: 5) // Every 5 min
```

## Array CRUD

```
// Find
firstIndex(of: x) // O(n)
```

```
// Insert
append(x) // O(1)
append(contentsOf: anArray)
insert(x, at: i) // O(n)
```

It is important to note that `append`

**O(1)** is much faster than `insert`

.

```
// Remove
remove(at: i) // O(n)
removeAll(where: {..})
dropFirst(x)
let last = popLast() // O(1)
```

```
// Move
move(fromOffsets:toOffset:)
```

## Mutate

```
sorted()
reversed()
shuffled()
swapAt()
```

There are more ops using your own predicate: `max(by:)`

, `sorted(by:)`

, `filter()`

, `map()`

## Partition

`partition(by:)`

is a powerful API, and quite advanced. It reorders the sequence by a predicate, such that the right half **satisfy the predicate** (while left half does not).

It returns the index of the first index in the right half.

```
let p = array.partition { .. }
let h1 = list[..<p] // Left half
let h2 = list[p...] // Right half
```

Note that it is an **unstable partition**, which means the order in both half are not preserved. There is an internal `halfStablePartition`

which will have the 1st half retain the original order, and also a `stablePartition`

which will have both half retain the original order.

If don’t know *Crusty*, read this up.

## Equatable

To compare and sort, the type should implement `Equatable`

protocol.

```
extension MyClass: Equatable {
public static func == (lhs: MyClass, rhs: MyClass) -> Bool {
return lhs.foo == rhs.foo
}
}
```

## Identity Comparison ===

There is an op `===`

for identity comparison eg. *are they the same instances?*

```
// For example, in the above Equatable implementation, we could also compare their identities
return lhs === rhs
```

## Dictionary O(1) access

An optimizing trick is to make use of the quick O(1) operation when accessing a dictionary, since they are hashed.

The trade off is that the setup takes O(n), and a space of O(n). And you need the type to be hashable.

## Hashable

```
extension MyClass: Hashable {
public func hash(into hasher: inout Hasher) {
hasher.combine(ObjectIdentifier(self).hashValue)
}
}
```