I was once asked "What is the best way to combine arrays?" This question is quite vague, and can mean a few different things.

### Concatenation

Concatenation is to append one thing to another. For example, concatenating the arrays **[1,2,3]** and **[4,5,6]** will give you **[1,2,3,4,5,6]**. This can be done in a few ways in Ruby.

The first is the plus operator. This will append one array to the end of another, creating a third array with the elements of both.

```
a = [1,2,3]
b = [4,5,6]
c = a + b
```

Alternatively, use the **concat** method (the + operator and concat method are functionally equivalent).

```
a = [1,2,3]
b = [4,5,6]
c = a.concat(b)
```

However, if you're doing a lot of these operations you may wish to avoid this. Object creation is not free, and every one of these operations creates a third array. If you want to modify an array in place, making it longer with new elements you can use the << operator. However, if you try something like this, you'll get an unexpected result.

```
a = [1,2,3]
a << [4,5,6]
```

Instead of the expected **[1,2,3,4,5,6]** array we get **[1,2,3,[4,5,6]]**. This makes sense, the append operator takes the object you give it and appends it to the end of the array. It didn't know or care that you tried to append another array to the array. So we can loop over it ourselves.

```
a = [1,2,3]
[4,5,6].each {|i| a << i }
```

### Set Operations

The world "combine" can also be used to describe the set operations.

The basic set operations of intersection, union and difference are available in Ruby. Remember that "sets" describe a set of objects (or in mathematics, numbers) that are unique in that set. For example, if you were to do a set operation on the array **[1,1,2,3]** Ruby will filter out that second 1, even though 1 may be in the resulting set.

So be aware that these set operations are different than list operations. Sets and lists are fundamentally different things.

You can take the union of two sets using the **|** operator. This is the "or" operator, if an element is in one set or the other, it's in the resulting set. So the result of **[1,2,3] | [3,4,5]** is **[1,2,3,4,5]** (remember that even though there are two threes, this is a set operation, not a list operation).

The intersection of two sets is another way to combine two sets. Instead of an "or" operation, the intersection of two sets is an "and" operation. The elements of the resultant set are those in *both* sets. And, being an "and" operation, we use the & operator. So the result of **[1,2,3] & [3,4,5]** is simply **[3]**.

Finally, another way to "combine" two sets is take their difference. The difference of two sets is the set of all objects in the first set that are *not* in the second set. So **[1,2,3] - [3,4,5]** is **[1,2]**.

### Zipping

Finally, there is "zipping." Two arrays can be zipped together combining them in a rather unique way. It's best to just show it first, and explain after. The result of **[1,2,3].zip([3,4,5])** is **[ [1,3], [2,4], [3,5] ]**. So what happened here? The two arrays were combined, the first element being a list of all elements in the first position of both arrays.

Zipping is a bit of a strange operation and you may not find much use for it. Its purpose is to combine two arrays whose elements closely correlate.