EMZETT.
Login

Kurz: Das ist der Kern des Ruby-Stils:

Teil des Kurses Ruby

Kapitel 4 von 12 im Kurs Ruby (Abschnitt „Datenstrukturen“). Mit Fortschritt, Quiz und Zertifikat auf der Lernseite.

Arrays

a = [5, 3, 9, 1]
a << 7                       # anhängen
a.push(2)
a.unshift(0)                  # vorne einfügen
p a
p a.pop, a.shift
p a, a.length, a.first, a.last, a[1], a[-1], a[1..2], a[1, 2], a.first(2), a.last(2)
a.delete(9)
a.insert(1, 99)
p a
p a.include?(99), a.index(99), a.sort, a.sort.reverse, a.sort { |x, y| y <=> x }
p a.min, a.max, a.sum, a.minmax, a.take(2), a.drop(2)
p [1, 2, 2, 3, 3, 3].uniq, [1, [2, [3]]].flatten, [3, 1, 2].reverse, [1, 2, 3].rotate
p [1, 2, 3] + [4], [1, 2, 3, 4] - [2, 3], [1, 2] * 2, [1, 2, 3] & [2, 3, 4], [1, 2] | [2, 3]
p [1, 2, 3].zip(%w[a b c]), [[1, :a], [2, :b]].to_h, [1, 2, 3].each_slice(2).to_a
p [1, 2, 3, 4].each_cons(2).to_a, [3, 1, 2].sort_by { |x| -x }, %w[bb a ccc].sort_by(&:length)
p Array.new(3, 0), Array.new(3) { |i| i * i }, [nil, 1, nil].compact
p [1, 2, 3].sample.class, [1, 2, 3].shuffle.length
x, y, *rest = [1, 2, 3, 4]
p x, y, rest

Ausgabe:

[0, 5, 3, 9, 1, 7, 2]
2
0
[5, 3, 9, 1, 7]
5
5
7
3
7
[3, 9]
[3, 9]
[5, 3]
[1, 7]
[5, 99, 3, 1, 7]
true
1
[1, 3, 5, 7, 99]
[99, 7, 5, 3, 1]
[99, 7, 5, 3, 1]
1
99
115
[1, 99]
[5, 99]
[3, 1, 7]
[1, 2, 3]
[1, 2, 3]
[2, 1, 3]
[2, 3, 1]
[1, 2, 3, 4]
[1, 4]
[1, 2, 1, 2]
[2, 3]
[1, 2, 3]
[[1, "a"], [2, "b"], [3, "c"]]
{1=>:a, 2=>:b}
[[1, 2], [3]]
[[1, 2], [2, 3], [3, 4]]
[3, 2, 1]
["a", "bb", "ccc"]
[0, 0, 0]
[0, 1, 4]
[1]
Integer
3
1
2
[3, 4]

Blöcke mit Collections: map, select, reduce

Das ist der Kern des Ruby-Stils:

z = [1, 2, 3, 4, 5, 6]
p z.map { |x| x * x }
p z.select(&:even?)              # &:name ist Kurzform für { |x| x.name }
p z.reject(&:even?)
p z.find { |x| x > 3 }
p z.partition { |x| x > 3 }
p z.group_by { |x| x % 3 }
p z.each_with_object({}) { |x, h| h[x] = x * x }
p z.reduce(:+), z.reduce(1) { |acc, x| acc * x }, z.inject { |a, b| a - b }
p z.count(&:even?), z.any? { |x| x > 5 }, z.all? { |x| x > 0 }, z.none? { |x| x > 9 }
p z.take_while { |x| x < 4 }, z.drop_while { |x| x < 4 }
p z.min_by { |x| (x - 4).abs }, z.max_by { |x| x % 4 }
p z.sum { |x| x * 2 }, z.tally, %w[a b a].tally
p z.each_with_index.map { |x, i| x * i }
p z.chunk_while { |a, b| b == a + 1 }.to_a
p z.flat_map { |x| [x, x] }.first(4)
p z.filter_map { |x| x * 2 if x.odd? }

Ausgabe:

[1, 4, 9, 16, 25, 36]
[2, 4, 6]
[1, 3, 5]
4
[[4, 5, 6], [1, 2, 3]]
{1=>[1, 4], 2=>[2, 5], 0=>[3, 6]}
{1=>1, 2=>4, 3=>9, 4=>16, 5=>25, 6=>36}
21
720
-19
3
true
true
true
[1, 2, 3]
[4, 5, 6]
4
3
42
{1=>1, 2=>1, 3=>1, 4=>1, 5=>1, 6=>1}
{"a"=>2, "b"=>1}
[0, 2, 6, 12, 20, 30]
[[1, 2, 3, 4, 5, 6]]
[1, 1, 2, 2]
[2, 6, 10]

Hashes

Ein Hash ist eine Zuordnung von Schlüsseln zu Werten (Dictionary). Er merkt sich die Einfügereihenfolge.

person = { name: "Mia", alter: 17, "stadt" => "Berlin" }
puts person[:name], person["stadt"], person[:unbekannt].inspect
person[:hobby] = "Judo"
person.delete(:alter)
p person
p person.keys, person.values, person.length, person.key?(:name), person.value?("Judo")
p person.fetch(:name), person.fetch(:x, "Standard"), person.dig(:name)
begin
  person.fetch(:fehlt)
rescue KeyError => e
  puts "KeyError: #{e.message}"
end
 
preise = { brot: 2.5, milch: 1.2, käse: 4.0 }
preise.each { |produkt, preis| puts "#{produkt}: #{preis}" }
p preise.map { |k, v| [k, v * 2] }.to_h
p preise.transform_values { |v| v.round }
p preise.select { |_, v| v > 2 }
p preise.reject { |_, v| v > 2 }
p preise.min_by { |_, v| v }, preise.sort_by { |_, v| -v }.first
p preise.sum { |_, v| v }
p preise.to_a.first, preise.invert.first
p preise.merge({ brot: 3.0, eier: 2.0 }) { |_, alt, neu| (alt + neu) / 2 }
 
zaehler = Hash.new(0)               # Standardwert 0
"mississippi".each_char { |c| zaehler[c] += 1 }
p zaehler
gruppen = Hash.new { |h, k| h[k] = [] }
%w[apfel birne banane ananas].each { |w| gruppen[w[0]] << w }
p gruppen
 
verschachtelt = { nutzer: { name: "Tom", adresse: { ort: "Köln" } } }
puts verschachtelt.dig(:nutzer, :adresse, :ort)
puts verschachtelt.dig(:nutzer, :telefon, :nr).inspect
 
name, alter = { name: "Zoe", alter: 20 }.values_at(:name, :alter)
puts "#{name} #{alter}"
p({ a: 1, b: 2 }.filter_map { |k, v| k if v > 1 })

Ausgabe:

Mia
Berlin
nil
{:name=>"Mia", "stadt"=>"Berlin", :hobby=>"Judo"}
[:name, "stadt", :hobby]
["Mia", "Berlin", "Judo"]
3
true
true
"Mia"
"Standard"
"Mia"
KeyError: key not found: :fehlt
brot: 2.5
milch: 1.2
käse: 4.0
{:brot=>5.0, :milch=>2.4, :"k\u00E4se"=>8.0}
{:brot=>3, :milch=>1, :"k\u00E4se"=>4}
{:brot=>2.5, :"k\u00E4se"=>4.0}
{:milch=>1.2}
[:milch, 1.2]
[:"k\u00E4se", 4.0]
7.7
[:brot, 2.5]
[2.5, :brot]
{:brot=>2.75, :milch=>1.2, :"k\u00E4se"=>4.0, :eier=>2.0}
{"m"=>1, "i"=>4, "s"=>4, "p"=>2}
{"a"=>["apfel", "ananas"], "b"=>["birne", "banane"]}
Köln
nil
Zoe 20
[:b]

Bereiche (Ranges)

p (1..5).to_a, (1...5).to_a, ('a'..'e').to_a
p (1..10).step(3).to_a, (1..5).sum, (1..5).include?(3), (1..5) === 7
p (1..Float::INFINITY).lazy.map { |x| x * 2 }.first(3)
p (1..).first(3)
puts (10..1).to_a.inspect, 10.downto(8).to_a.inspect
p [10, 20, 30, 40][1..], [10, 20, 30, 40][..1], "Ruby"[1..2]

Ausgabe:

[1, 2, 3, 4, 5]
[1, 2, 3, 4]
["a", "b", "c", "d", "e"]
[1, 4, 7, 10]
15
true
false
[2, 4, 6]
[1, 2, 3]
[]
[10, 9, 8]
[20, 30, 40]
[10, 20]
"ub"

Mengen

require "set"
a = Set.new([1, 2, 3])
b = Set[2, 3, 4]
p a | b, a & b, a - b, a.include?(2), a.add(9).size, a.subset?(Set[1, 2, 3, 9, 10])

Ausgabe:

#<Set: {1, 2, 3, 4}>
#<Set: {2, 3}>
#<Set: {1}>
true
4
true

Merke

  • Arrays: <<, push, pop, sort, uniq, zip, flatten; Zugriff a[0], a[1..2]
  • Blöcke: map, select, reject, reduce, group_by, tally, sum, each_with_object
  • Hashes: { name: "Mia" }, fetch, dig, Hash.new(0), transform_values, merge
  • Ranges (1..5) und (1...5), auch endlos und lazy
  • Set für Mengen

Übungsaufgabe

Zähle die Buchstaben eines Satzes mit tally, sortiere sie nach Häufigkeit und gib die drei häufigsten aus.

Quiz zur Selbstkontrolle

Weiter im Kurs

Zurück: Kontrollfluss und Schleifen

Weiter: Methoden, Blöcke, Procs und Lambdas

Alle Kapitel: Ruby im Überblick