Les tableaux en Ruby

Salut, en lisant des message discord à propos de code relatif aux tableaux, je vois souvent des choses comme array[rand(array.length)] ou des boucle for. C'est relativement triste puis-ce que Ruby a implémenter un certain nombre de méthode permettant de transformer une collection d'entrée en ce que vous avez besoin. C'est presque aussi puissant que du SQL mais avec des chaines et méthodes & blocks Ruby!

Dans cette page, je vais vous montrer des façons d'utiliser les tableaux pour faire ce que vous voulez. Si vous voulez en voir plus, n'hésitez pas à regarder la Documentation officielle de Ruby.

Créer un tableau

En Ruby il existe plusieurs façons de créer un tableau, en fonction de ce dont vous avez besoin, vous pouvez l'écrire d'une différent façon. Chaque chapitre de cette section montrera une des façons préférée de créer un tableau.

Créer un tableau vide

La meilleure façon de créer un tableau vide est d'utiliser l'écriture littérale:

new_array = []

Créer un tableau de quelconque valeurs

La plupart du temps, vous créerez des tableaux de valeurs quelconques. Si ça ne vient pas d'un calcul de données (ex, le tableau est utilisé comme des données statiques), vous pouvez simplement utiliser l'écriture littérale:

new_array = [
  1,
  'string',
  :symbol
]

Créer un tableau de chaine de caractères

Si vous avez besoin de créer un tableau de chaines de caractères, Ruby a une écriture spécifique pour ça. Cette écriture simplifie la création car vous n'aurez pas besoin d'écrire les virgules et les guillemet anglais.

Voic quelques exemples:

array_of_string1 = %w[word1 word2 string\ with\ spaces last_word]
# Result: ["word1", "word2", "string with spaces", "last_word"]

array_of_string2 = %w[
  word1 word2
  string\ with\ spaces
  last_word
]
# Result: ["word1", "word2", "string with spaces", "last_word"]

Créer un tableau de Symboles

D'une façon similaire, vous pouvez créer un tableau de Symboles sans avoir à écrire le caractère : et les virgules. C'est très pratique car les Symboles sont au coeur de Ruby. Par exemple, les objets sont identifiés avec un Symbole dans Pokémon SDK, le symbole de la potion est :potion.

Voici des exemples:

array_of_symbol1 = %i[potion elixir candy]
# Result: [:potion, :elixir, :candy]

array_of_symbol2 = %i[
  potion
  elixir
  candy
]
# Result: [:potion, :elixir, :candy]

Créer un tableau à partir d'un autre type de séquence

En général, les séquence ou énumérateurs ont une méthode to_a qui permet de la convertir en tableau. Voici quelques exemples:

array_of_1_upto_5_included = (1..5).to_a
# Result: [1, 2, 3, 4, 5]

alphabet = ('a'..'z').to_a
# Result: ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]

array_of_chars = "My string".each_char.to_a
# Result: ["M", "y", " ", "s", "t", "r", "i", "n", "g"]

array_of_lines = "My string\nWith lines".each_line.to_a
# Result: ["My string\n", "With lines"]

array_of_bytes = "\x01\x25\xFF".each_byte.to_a
# Result: [1, 37, 255]

Récupérer une valeur dans un tableau

Les tableaux stockent une collection de données. Vous avez souvent besoin d'en récupérer une valeur. Heureusement, Ruby n'est pas le C, vous avez tout un tas de méthodes vous permettant de récupérer des données selon vos besoins!

Obtenir la première ou dernière valeur d'un tableau

Comme vous devriez surement le savoir, les tableaux ont l'opérateur [] qui permet de récupérer un valeur si vous en connaissez l'index. Malheureusement, parfois vous ne connaissez pas toujours l'index d'un élément, en particulier le dernier. C'est pourquoi Ruby a implémenté la méthode last et son opposé first qui permettent respectivement de récupérer le dernier et le premier élément d'un tableau.

Ceci rend le code infiniment plus lisible car lorsque vous avez étudié les Maths, le premier index est 1 et non 0. Le dernier index en tant que -1 est assez illogique et parfois mystérieux.

Voici des exemple d'usage de ces méthodes:

my_array = [1, 2, 3, 4, 5]
first_element = my_array.first
# Result: 1
last_element = my_array.last
# Result: 5

Trouver une valeur dans un tableau

Les tableaux stockent plusieurs type de données. Parfois, vous cherchez un élément en particulier. Heureusement, Ruby a plusieurs méthodes pour réaliser cela. La méthode dont on parle est tout simplement find, elle prend un block en paramètre pour décrire ce que vous cherchez et vous renvoie la première valeur qui correspond à vos critères.

Voici quelques exemples:

array_of_words = %w[Madrid Paris London Berlin]
# Find the first word that starts with L
word_starting_with_l = array_of_words.find { |word| word.start_with?('L') }
# Result: "London"

array_of_numbers = [1, 5, 6, 2, 3]
# Find the first element that is even
first_even_number = array_of_numbers.find(&:even?)
# Result: 6
# Note: find(&:even?) is strictly equivalent to find { |number| number.even? }

Trouver l'index d'un élément dans un tableau

D'une manière équivoque, vous cherchez peut-être juste la position de cet élément dans le tableau. Si vous connaissez déjà la valeur vous pouvez utiliser la méthode index, sinon vous pouvez utiliser la méthode find_index en donnant un block qui décrit à quoi ressemble la valeur que vous cherchez.

Voici quelques exemples:

array_of_numbers = [1, 5, 3, 2]
# Find the index of 5 in the array
index_of5 = array_of_numbers.index(5)
# Result: 1

array_of_string = %w[coffee tea water soda]
# Find the index of the first word starting with w
index_of_word_starting_with_w = array_of_string.find_index { |word| word.start_with?('w') }
# Result: 2

Obtenir un élément de manière aléatoire

En Ruby, c'est vraiment simple d'obtenir un élément de manière aléatoire dans un tableau. Il suffit d'appeler la méthode sample:

array_of_numbers = [1, 2, 3, 4, 5, 6]
# Getting any element at random
random_element = array_of_numbers.sample
# Result: Any of the value from the array (cannot predict without knowing the seed ;))

# Getting any element at random using a Random object
predictable_element = array_of_numbers.sample(random: Random.new(5))
# Result: 4

Obtenir le plus petit ou le plus grand élément d'un tableau

Si vous avez besoin de la plus petite ou plus grande valeur d'un tableau, il existe les méthodes min et max. Si votre tableau ne contient pas des nombres, vous pouvez utiliser min_by et max_by pour décrire la grandeur de vos éléments!

Voici des exemples:

array_of_number = [5, -3, 2, 66, 4]
highest_number = array_of_number.max
# Result: 66
lowest_number = array_of_number.min
# Result: -3

array_of_string = %w[hello worlds !]
longer_string = array_of_string.max_by(&:size)
# Result: "worlds"
smaller_string = array_of_string.min_by(&:size)

Récupérer des valeurs spéciales

Les tableaux possèdent également des méthodes permettant de récupérer des valeurs qui ne sont pas dans le tableau elles-même mais qui résultent de son contenu.

Obtenir la taille d'un tableau

Normalement, vous n'avez pas souvent besoin de cette valeur, mais au cas où, la méthode pour récupérer la taille d'un tableau est la même que pour les chaines de caractères: size

Exemple:

array_of_numbers = [1, 2, 3, 4, 5, 2]
# Getting the size of this array
size_of_array = array_of_numbers.size
# Result: 6

Obtenir la somme de tous les éléments

Pour calculer la somme de tous les éléments d'un tableau il suffit simplement d'appeler la méthode sum. Cette méthode peut également utiliser un block pour donner du sens à ce que vous sommez:

array_of_numbers = [1, 2, 3]
sum_of_numbers = array_of_numbers.sum
# Result: 6

array_of_string = ['a', 'ab', 'abc']
sum_of_sizes = array_of_string.sum(&:size)
# Result: 6

Compter les valeurs qui correspondent à un critère

Comme en SQL, la méthode count sert à ça. Vous pouvez lui donner les critères en block et elle vous renverra le nombre d'élément qui valident ces critères:

array_of_numbers = [1, 2, 3, 4, 5]
count_of_odd_numbers = array_of_numbers.count(&:odd?)
# Result: 3

Convertir l'intégralité du tableau en une autre valeur

Parfois, vous avez besoin de transformer un tableau en une tout autre valeur. La méthode qui permet ça s'appelle reduce. En JavaScript, si vous ne désirez pas utiliser lodash c'est souvent la méthode que vous utiliserez.

Voici un exemple de conversion de tableau:

array_of_sentence_badly_combined = ['My first', 'sentence', 'My second ', 'sentence.']
paragraph = array_of_sentence_badly_combined.reduce('') do |prev, curr|
  sentence = prev.rstrip
  continuation = curr.lstrip
  next sentence << continuation if continuation[0] == continuation[0].downcase
  next sentence << '. ' << continuation unless sentence.end_with?('.') || sentence.empty?
  next sentence << continuation
end

# Result: "My firstsentence. My secondsentence."

Vérifier si le tableau contient une valeur particulière

Parfois, vous voulez tester si le tableau contient une valeur qui correspond à certains critères. La méthode any? vous permet de faire cela, donnez lui un block et elle reverra un boolean indiquant si ce block a été validé au moins une fois.

Notez que si vous connaissez la valeur que vous voulez tester, vous pouvez simplement utiliser include?.

Voici des exemples:

array_of_number = [1, 2, 3, 4]
array_contains_even_number = array_of_number.any?(&:even?)
# Result: true
array_contains_zero = array_of_number.any?(&:zero?)
# Result: false
array_contains2 = array_of_number.include?(2)

Bonus pour vous. Si vous ne donnez aucun block à any?, vous pourrez plus ou moins tester si le tableau contient au moins un élément valide. (Tout sauf nil ou false).

Ceci peut être utile pour éviter d'écrire unless array.empty? si vous êtes certain que votre tableau doit contenir des valeurs valides.

empty_array = []
array_is_not_containing_value = empty_array.any?
# Result: false

array_containing_something = [0]
array_is_containing_value = array_containing_something.any?
# Result: true

array_containing_something_but_any_says_false = [false, nil]
bad_state_but_okeyish = array_containing_something_but_any_says_false.any?
# Result: false

Tester si aucun ou tous les éléments d'un tableau valide un critère

Comme pour any?, les tableaux ont la méthode none? et all? qui permettent de vérifier respectivement si aucune ou toute les valeurs d'un tableau correspondent aux critères donnés en block.

Exemple:

array_of_odd_numbers = [1, 3, 5]
all_odd = array_of_odd_numbers.all?(&:odd?)
# Result: true
none_even = array_of_odd_numbers.none?(&:even?)
# Result: true

Transformer les tableaux

L'une des choses que vous allez surement beaucoup faire avec les tableaux, c'est les transformer. En dehors de push, pop et delete, Ruby définit un certain nombre de méthodes permettant de transformer les tableaux selon vos besoins.

Notez que la majorité de ces méthodes n'affectent pas le tableau d'origine, si vous voulez que le tableau d'origine soit affecté, il faudra utiliser la variante de ces méthodes qui finissent par un point d'exclamation.

Supprimer les nils d'un tableau

Il peut vous arriver que votre tableau finisse avec des valeurs nil. Heureusement, il existe une méthode pour tous les supprimer: compact.

Voici un exemple:

array_with_nils = [1, nil, 2, 3, nil]
array_without_nils = array_with_nils.compact
# Result: [1, 2, 3]

Filtrer les valeurs d'un tableau

Ruby défini deux méthodes pour filtrer les valeurs d'un tableau

  • select to garder toute les valeurs qui correspondent au critère
  • reject to supprimer toute les valeurs qui correspond au critère
array_of_number = [0, 1, 2, 3, 4]
array_of_odd_numbers = array_of_number.select(&:odd?)
# Result: [1, 3]
array_of_number_that_arent_odd = array_of_number.reject(&:odd?)
# Result: [0, 2, 4]

Transformer les valeurs d'un tableau

Parfois, vous avez besoin de convertir le contenu du tableau, pour cela vous avez la méthode map.

Exemple:

array_of_number = [1, 2, 3]
array_of_twice_the_number = array_of_number.map { |n| n * 2 }
# Result: [2, 4, 6]

Pivoter un tableau

Si vous avez utilisé un DSP une fois dans votre vie, vous avez à quel point ça peut être pratique de pivoter un tableau (ou d'avoir des tableau purement circulaire). Ruby possède une méthode pour réaliser ce genre d'opération: rotate

Voici quelques exemples:

my_array = [1, 2, 3, 4]
my_array_rotated_to_left = my_array.rotate(1)
# Result: [2, 3, 4, 1]
my_array_rotated_to_right = my_array.rotate(-1)
# Result: [4, 1, 2, 3]

Mélanger un tableau

Si vous avez besoin de mélanger un tableau, utilisez la méthode shuffle. Exemple:

my_array = [1, 2, 3, 4]
my_array_in_random_order = my_array.shuffle
# Example result: [2, 3, 4, 1]
my_array_in_seeded_order = my_array.shuffle(random: Random.new(6))
# Result: [1, 4, 2, 3]

Crédits

Image de couverture: Wiki Media Commons

Article écrit par Nuri Yuri