# Day 03 - Array Methods in Ruby

Methods are so handy when you play with arrays in Ruby. Here are some useful methods I used while doing the [Codewars](%5Bhttps://www.codewars.com%5D) challenge.

# chars()

`chars` returns an array of characters in strings. This is a shorthand for `each_char.to_a`. Let's take a look at these 2 methods separately.

## each\_char()

`each_char` passes each character in the string to the given block, or returns an enumerator if no block is given.

```ruby
"hello".each_char {|c| print c, ' ' }
#=> h e l l o
```

One thing worth mentioning is that `each_char` is quite similar to `each` method in Ruby.

The difference is that you can pass an argument to `each` for splitting the string but you can't do the same with `each_char` .

The argument will be passed to the supplied block as the record separator ($/ by default). If no record separator is provided, the string is split into paragraphs delimited by multiple successive newlines.

You can check the example below:

```ruby
# Example one
"hello\nworld".each {|s| p s}
#=>  "hello\n"
#=>  "world"

# Example Two
"hello\nworld".each('l') {|s| p s}
#=>  "hel"
#=>  "l"
#=>  "o\nworl"
#=>  "d"

# Example Three
"hello\n\n\nworld".each('') {|s| p s}
#=>  "hello\n\n\n"
#=>  "world"
```

## to\_a()

`to_a` simply turns the *obj into an array.*

```ruby
"hello".to_a    #=> ["hello"]
Time.new.to_a   #=> [39, 54, 8, 9, 4, 2003, 3, 99, true, "CDT"]
```

## Combine two into one

Therefore, `chars` is the easiest and cleanest way to turn a string into an array without passing anything by combining the power of `each_char` and `to_a`.

```ruby
"abcdef".chars
#=> ["a", "b", "c", "d", "e", "f"]
```

* * *

# include?()

When you want to check whether an item is stored inside the array, the best method is to use `include?` . It turns `true` if the given *object* is present in `self` (that is if any element == object), otherwise returns `false`.

```ruby
a = [ "a", "b", "c" ]
a.include?("b")   #=> true
a.include?("z")   #=> false

#These also work
a.include? "b"    #=> true
a.include? "z"    #=> false
```

* * *

# uniq()

`uniq` is super useful when you need to **remove duplicate values in an array**. It returns a new array without repeated items.

You can also pass a block to it and it then will use the return value of the block for comparison.

```ruby
a = [ "a", "a", "b", "b", "c" ]
a.uniq   # => ["a", "b", "c"]

b = [["student","sam"], ["student","george"], ["teacher","matz"]]
b.uniq { |s| s.first } # => [["student", "sam"], ["teacher", "matz"]]
```

* * *

# sort()

`sort` returns a new array created by sorting self. You can also pass a block to it by using the `<=>` operator.

The block must implement a comparison between `a` and `b` and:

1.  return **an integer less than 0** when `b` follows `a` ,
    
2.  return **0** when `a` and `b` are equivalent, or
    
3.  return **an integer greater than 0** when `a` follows `b`.
    

Please remind the result is not *guaranteed to be stable*. When the comparison of two elements returns 0, the order of the elements is unpredictable.

```ruby
ary = [ "d", "a", "e", "c", "b" ]
ary.sort                     #=> ["a", "b", "c", "d", "e"]
ary.sort { |a, b| b <=> a }  #=> ["e", "d", "c", "b", "a"]
```

## reverse()

**Bonus tip**: Other than using `<=>` operator, you can rearrange the array in descending order by chaining the `reverse` method with `sort` method.

```ruby
ary.sort.reverse    #=> ["e", "d", "c", "b", "a"]
```

* * *

# split() & join()

Last but not least, `split` and `join` are the two I use most frequently while doing Codewars challenges.

## split()

`split` divides the string into substrings based on a delimiter, returning an array of these substrings.

### Passing a string

If the pattern is a `String`, then its contents are used as the delimiter when splitting the string.

You can also pass a number as the second argument `limit`. If the number is *positive*, for example `4`, **at most** **4 split substrings** will be returned. If *negative*, there is no limit to the number of fields returned.

```ruby
"mellow yellow".split("ello")   #=> ["m", "w y", "w"]
"1,2,,3,4,,".split(',')         #=> ["1", "2", "", "3", "4"]

"1,2,,3,4,,".split(',', 1)      #=> ["1,2,,3,4,,"]
"1,2,,3,4,,".split(',', 4)      #=> ["1", "2", "", "3,4,,"]
"1,2,,3,4,,".split(',', -4)     #=> ["1", "2", "", "3", "4", "", ""]
```

### Passing nil or a single space

If the pattern is a single space, *str* is split on **whitespace**, with leading whitespace and runs of contiguous whitespace characters ignored.

If the pattern is nil, the value of `$;` is used. If `$;` is nil (which is the default), *str* is split on whitespace as if ‘ ’ were specified.

```ruby
" now's  the time".split        #=> ["now's", "the", "time"]
" now's  the time".split(' ')   #=> ["now's", "the", "time"]
```

### Passing a Regexp

If the pattern is a Regexp, *str* is divided where the pattern matches. Whenever the pattern matches a zero-length string, *str* is split into individual characters. If the pattern contains groups, the respective matches will be returned in the array as well.

```ruby
" now's  the time".split(/ /)   #=> ["", "now's", "", "the", "time"]
"1, 2.34,56, 7".split(%r{,\s*}) #=> ["1", "2.34", "56", "7"]
"hello".split(//)               #=> ["h", "e", "l", "l", "o"]
"hello".split(//, 3)            #=> ["h", "e", "llo"]
"hi mom".split(%r{\s*})         #=> ["h", "i", "m", "o", "m"]

"1:2:3".split(/(:)()()/, 2)     #=> ["1", ":", "", "", "2:3"]
```

## join()

`join` returns a string created by converting each element of the array to a string, separated by **the given separator**.

For nested arrays, join is applied recursively:

```ruby
[ "a", "b", "c" ].join        #=> "abc"
[ "a", "b", "c" ].join("-")   #=> "a-b-c"

[ "a", [1, 2, [:x, :y]], "b" ].join("-")   #=> "a-1-2-x-y-b"
```

* * *

# Challenge yourself

After learning all these, you are ready to finish this [kata](https://www.codewars.com/kata/5656b6906de340bd1b0000ac/ruby) on Codewars. Give it a try!
