Takip et

Ruby’de Dizilerle Çalışmak: Kapsamlı Bir Rehber

Ruby’de Dizilerle Çalışmak: Kapsamlı Bir Rehber Programlamanın temel yapı taşlarından biri olan diziler (arrays), aynı veya farklı veri tip

Ruby’de Dizilerle Çalışmak: Kapsamlı Bir Rehber

Programlamanın temel yapı taşlarından biri olan diziler (arrays), aynı veya farklı veri tiplerindeki elemanları sıralı bir şekilde depolayan koleksiyonlardır. Ruby, esnek ve güçlü dizi manipülasyon yetenekleriyle geliştiricilere zengin bir araç seti sunar. Bu makale, Ruby’deki dizilerin temellerinden başlayarak ileri seviye kullanımlarına, performans ipuçlarına ve en iyi uygulamalara kadar geniş bir yelpazeyi kapsayacak ve Ruby ile dizilerle nasıl etkili bir şekilde çalışılacağını detaylandıracaktır. İster yeni başlayan bir Ruby geliştiricisi olun, ister deneyimli bir uzman, bu rehber diziler hakkındaki bilginizi pekiştirmek ve pratik becerilerinizi geliştirmek için değerli bilgiler sunacaktır.

Dizilerin Temelleri

Ruby’de diziler, Array sınıfının örnekleridir ve oldukça esnek yapıdadırlar. Farklı veri tiplerini (sayılar, metinler, objeler, hatta başka diziler) aynı dizide barındırabilirler. Diziler, sıfır tabanlı indeksleme kullanır, yani ilk elemanın indeksi 0’dır.

Dizi Oluşturma

Ruby’de dizi oluşturmanın birkaç yolu vardır:

* Boş bir dizi oluşturma:

bos_dizi = []
    # veya
    bos_dizi_2 = Array.new

* Elemanlarla birlikte dizi oluşturma:

sayilar = [1, 2, 3, 4, 5]
    isimler = ["Ali", "Ayşe", "Mehmet"]
    karisik_dizi = [1, "Merhaba", true, nil, 3.14]

* Array.new ile boyut ve başlangıç değeri belirterek:

on_elemanli_dizi = Array.new(10) # 10 adet nil içeren dizi
    sifirlar_dizisi = Array.new(5, 0) # [0, 0, 0, 0, 0]
    blok_ile_dizi = Array.new(3) { |i| i * 2 } # [0, 2, 4]

* %w (word array) kısayolu ile string dizileri oluşturma:
Bu yöntem, özellikle kelime listeleri için kullanışlıdır ve tırnak işaretlerinden kurtarır.

meyveler = %w[elma armut muz çilek] # ["elma", "armut", "muz", "çilek"]

Elemanlara Erişim

Dizi elemanlarına indeks numaraları aracılığıyla erişilir:

* İndeksleme ([]):

dizi = [10, 20, 30, 40, 50]
    puts dizi[0] # 10 (ilk eleman)
    puts dizi[3] # 40
    puts dizi[10] # nil (dizi dışı indeks)

* Negatif indeksleme: Dizinin sonundan başlayarak elemanlara erişmek için kullanılır. -1 son elemanı, -2 sondan ikinci elemanı temsil eder.

puts dizi[-1] # 50 (son eleman)
    puts dizi[-3] # 30

* at() metodu: [] operatörüne benzer bir işlev sunar.

puts dizi.at(0) # 10
    puts dizi.at(-1) # 50

* first ve last metotları: Dizinin ilk ve son elemanlarına doğrudan erişim sağlar. Ayrıca bir argüman alarak ilk/son N elemanı döndürebilirler.

puts dizi.first # 10
    puts dizi.last # 50
    puts dizi.first(2) # [10, 20]
    puts dizi.last(3) # [30, 40, 50]

* fetch() metodu: Geçersiz bir indekse erişildiğinde hata fırlatma veya varsayılan bir değer döndürme yeteneği sunar.

puts dizi.fetch(2) # 30
    # puts dizi.fetch(10) # IndexError: index 10 outside of array bounds
    puts dizi.fetch(10, "Yok") # "Yok" (varsayılan değer)

Eleman Ekleme ve Çıkarma

Dizilere eleman eklemek ve çıkarmak için çeşitli metotlar bulunur:

* Ekleme:
* push veya << (sona ekleme):

dizi = [1, 2, 3]
        dizi.push(4, 5) # [1, 2, 3, 4, 5]
        dizi << 6 # [1, 2, 3, 4, 5, 6]

* unshift (başına ekleme):

dizi.unshift(0) # [0, 1, 2, 3, 4, 5, 6]

* insert (belirli bir indekse ekleme):

dizi.insert(2, 99) # [0, 1, 99, 2, 3, 4, 5, 6]
        dizi.insert(4, "a", "b") # [0, 1, 99, 2, "a", "b", 3, 4, 5, 6]

* Çıkarma:
* pop (sondan çıkarma):

dizi = [1, 2, 3, 4, 5]
        son_eleman = dizi.pop # 5 (dizi şimdi [1, 2, 3, 4])
        iki_eleman = dizi.pop(2) # [3, 4] (dizi şimdi [1, 2])

* shift (baştan çıkarma):

ilk_eleman = dizi.shift # 1 (dizi şimdi [2])

* delete_at (belirli bir indeksteki elemanı çıkarma):

dizi = [10, 20, 30, 40]
        silinen = dizi.delete_at(1) # 20 (dizi şimdi [10, 30, 40])

* delete (belirli bir değeri olan tüm elemanları çıkarma):

dizi = [1, 2, 3, 2, 4]
        dizi.delete(2) # [1, 3, 4]

* compact (nil elemanları çıkarma):

dizi_nil = [1, nil, 2, nil, 3]
        dizi_nil.compact # [1, 2, 3]

Dizinin Boyutu ve Durumu

Dizinin boyutu, eleman sayısı veya boş olup olmadığını kontrol etmek için metotlar:

* length, size, count: Dizideki eleman sayısını döndürür. count ayrıca bir blok veya argüman alarak belirli koşulları sağlayan eleman sayısını da bulabilir.

dizi = [1, 2, 3, 4, 5]
    puts dizi.length # 5
    puts dizi.size # 5
    puts dizi.count # 5
    puts dizi.count(2) # 1 (2 sayısının kaç tane olduğunu sayar)
    puts dizi.count { |x| x > 3 } # 2 (3'ten büyük eleman sayısı)

* empty?: Dizi boşsa true, değilse false döndürür.

bos_dizi = []
    dolu_dizi = [1, 2]
    puts bos_dizi.empty? # true
    puts dolu_dizi.empty? # false

Diziler Üzerinde Yineleme (Iteration)

Ruby'nin en güçlü yanlarından biri, diziler üzerinde yineleme yapmak için sunduğu zengin metot setidir. Bu metotlar, kodu daha okunabilir ve işlevsel hale getirir.

each

Dizinin her elemanı üzerinde bir işlem yapmak için kullanılır. Orjinal diziyi değiştirmez ve kendisine çağrıldığı diziyi döndürür.

sayilar = [1, 2, 3, 4, 5]
sayilar.each do |sayi|
  puts "Sayı: #{sayi}"
end

Çıktı:

Sayı: 1

Sayı: 2

Sayı: 3

Sayı: 4

Sayı: 5

* each_with_index: Elemanlarla birlikte indekslerine de erişmek için kullanılır.

meyveler = ["elma", "armut", "muz"]
    meyveler.each_with_index do |meyve, indeks|
      puts "#{indeks}. #{meyve}"
    end
    # Çıktı:
    # 0. elma
    # 1. armut
    # 2. muz

map / collect

Dizinin her elemanını dönüştürerek yeni bir dizi oluşturan metotlardır. Orijinal dizi değişmez. map ve collect aynı işlevi görür.

sayilar = [1, 2, 3, 4]
kareler = sayilar.map { |sayi| sayi * sayi }
puts kareler.inspect # [1, 4, 9, 16]

isimler = ["ali", "ayşe", "mehmet"]
buyuk_isimler = isimler.collect(&:upcase) # Sembol proc kullanımı
puts buyuk_isimler.inspect # ["ALI", "AYŞE", "MEHMET"]

select / filter

Belirli bir koşulu sağlayan elemanları içeren yeni bir dizi oluşturur. select ve filter aynı işlevi görür.

sayilar = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
cift_sayilar = sayilar.select { |sayi| sayi % 2 == 0 }
puts cift_sayilar.inspect # [2, 4, 6, 8, 10]

uzun_isimler = %w[ali ayşe mehmet deniz]
filtreli_isimler = uzun_isimler.filter { |isim| isim.length > 4 }
puts filtreli_isimler.inspect # ["ayşe", "mehmet", "deniz"]

reject

Belirli bir koşulu sağlamayan elemanları içeren yeni bir dizi oluşturur. select'in tam tersidir.

sayilar = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
tek_sayilar = sayilar.reject { |sayi| sayi % 2 == 0 }
puts tek_sayilar.inspect # [1, 3, 5, 7, 9]

find / detect

Belirli bir koşulu sağlayan ilk elemanı döndürür. Eğer hiçbir eleman koşulu sağlamazsa nil döndürür.

sayilar = [1, 2, 3, 4, 5]
ilk_cift = sayilar.find { |sayi| sayi % 2 == 0 }
puts ilk_cift # 2

buyuk_sayi = sayilar.detect { |sayi| sayi > 10 }
puts buyuk_sayi.inspect # nil

reduce / inject

Dizideki tüm elemanları birleştirerek tek bir değer elde etmek için kullanılır. Toplama, çarpma, string birleştirme gibi işlemlerde çok faydalıdır.

sayilar = [1, 2, 3, 4, 5]
toplam = sayilar.reduce(0) { |accumulator, current_value| accumulator + current_value }
puts toplam # 15 (0 + 1 + 2 + 3 + 4 + 5)

Başlangıç değeri olmadan ilk elemanı accumulator olarak kullanır

carpim = sayilar.inject { |acc, val| acc * val } puts carpim # 120 (1 2 3 4 5) kelimeler = ["Ruby", "çok", "güçlüdür"] cumle = kelimeler.reduce("") { |acc, word| acc + word + " " }.strip puts cumle # "Ruby çok güçlüdür"

any?, all?, none?, one?

Dizideki elemanların belirli koşulları sağlayıp sağlamadığını kontrol eden sorgulama metotlarıdır.

* any?: En az bir eleman koşulu sağlıyorsa true döndürür.

sayilar = [1, 2, 3, 4, 5]
    puts sayilar.any? { |sayi| sayi > 4 } # true
    puts sayilar.any? { |sayi| sayi > 10 } # false

* all?: Tüm elemanlar koşulu sağlıyorsa true döndürür.

puts sayilar.all? { |sayi| sayi > 0 } # true
    puts sayilar.all? { |sayi| sayi % 2 == 0 } # false

* none?: Hiçbir eleman koşulu sağlamıyorsa true döndürür.

puts sayilar.none? { |sayi| sayi > 10 } # true
    puts sayilar.none? { |sayi| sayi % 2 == 0 } # false

* one?: Sadece bir eleman koşulu sağlıyorsa true döndürür.

puts sayilar.one? { |sayi| sayi == 3 } # true
    puts sayilar.one? { |sayi| sayi % 2 == 0 } # false (2 ve 4 var)

Dizi Manipülasyonu ve Dönüşümü

Ruby dizileri, elemanlarını yeniden düzenlemek, birleştirmek, bölmek ve farklı formatlara dönüştürmek için zengin bir dizi metot seti sunar.

Birleştirme ve Çıkarma

* + operatörü: İki diziyi birleştirerek yeni bir dizi oluşturur.

dizi1 = [1, 2]
    dizi2 = [3, 4]
    birlesik_dizi = dizi1 + dizi2 # [1, 2, 3, 4]

* - operatörü: Bir diziden diğerinde bulunan elemanları çıkararak yeni bir dizi oluşturur.

dizi_a = [1, 2, 3, 4, 5]
    dizi_b = [2, 4]
    fark_dizi = dizi_a - dizi_b # [1, 3, 5]

* concat: Bir dizinin sonuna başka bir dizinin elemanlarını ekler. Orijinal diziyi değiştirir.

dizi1 = [1, 2]
    dizi2 = [3, 4]
    dizi1.concat(dizi2) # dizi1 şimdi [1, 2, 3, 4]

Çarpma

operatörü: İki farklı şekilde kullanılabilir:
* Bir tamsayı ile çarpıldığında, diziyi o kadar kez tekrarlayan yeni bir dizi oluşturur.
* Bir string ile çarpıldığında, dizinin elemanlarını o string ile birleştirir.

dizi = [1, 2]
    tekrarlanan_dizi = dizi * 3 # [1, 2, 1, 2, 1, 2]

    kelimeler = ["elma", "armut", "muz"]
    birlesik_string = kelimeler * ", " # "elma, armut, muz" (join metoduna benzer)

Sıralama

* sort: Diziyi doğal sırasına göre sıralayarak yeni bir dizi döndürür. Orijinal diziyi değiştirmez.

sayilar = [3, 1, 4, 1, 5, 9, 2]
    sirali_sayilar = sayilar.sort # [1, 1, 2, 3, 4, 5, 9]

    isimler = ["Ayşe", "Ali", "Zeynep"]
    sirali_isimler = isimler.sort # ["Ali", "Ayşe", "Zeynep"]

* sort!: Diziyi yerinde (in-place) sıralar.

sayilar = [3, 1, 4]
    sayilar.sort! # sayilar şimdi [1, 3, 4]

* sort_by: Belirli bir kritere göre sıralama yapmak için blok alır.

kisiler = [{ad: "Ali", yas: 30}, {ad: "Ayşe", yas: 25}, {ad: "Mehmet", yas: 35}]
    yasa_gore_sirali = kisiler.sort_by { |kisi| kisi[:yas] }
    # [{ad: "Ayşe", yas: 25}, {ad: "Ali", yas: 30}, {ad: "Mehmet", yas: 35}]

* reverse / reverse!: Diziyi tersine çevirir. reverse yeni bir dizi döndürürken, reverse! orijinal diziyi değiştirir.

dizi = [1, 2, 3]
    ters_dizi = dizi.reverse # [3, 2, 1]
    dizi.reverse! # dizi şimdi [3, 2, 1]

Benzersiz Elemanlar

* uniq / uniq!: Dizideki yinelenen elemanları kaldırarak benzersiz elemanlardan oluşan yeni bir dizi döndürür. uniq! orijinal diziyi değiştirir.

sayilar = [1, 2, 2, 3, 1, 4]
    benzersiz_sayilar = sayilar.uniq # [1, 2, 3, 4]

Düzleştirme (Flattening)

* flatten / flatten!: İç içe dizileri tek bir düz diziye dönüştürür. flatten! orijinal diziyi değiştirir.

ic_ice_dizi = [1, [2, 3], [4, [5, 6]]]
    duz_dizi = ic_ice_dizi.flatten # [1, 2, 3, 4, 5, 6]

Bir argüman alarak belirli bir seviyeye kadar düzleştirebilirsiniz:

duz_dizi_bir_seviye = ic_ice_dizi.flatten(1) # [1, 2, 3, 4, [5, 6]]

Dilimleme (Slicing)

Dizinin bir bölümünü (bir alt diziyi) almak için kullanılır.

* [] operatörü ile aralık belirtme: Başlangıç indeksi ve uzunluk veya bir aralık (.. veya ...) ile.

dizi = [10, 20, 30, 40, 50]
    puts dizi[1, 3].inspect # [20, 30, 40] (1. indeksten başlayarak 3 eleman)
    puts dizi[0..2].inspect # [10, 20, 30] (0'dan 2'ye kadar, 2 dahil)
    puts dizi[0...2].inspect # [10, 20] (0'dan 2'ye kadar, 2 hariç)

* slice: [] operatörü ile aynı işlevi görür.

puts dizi.slice(1, 2).inspect # [20, 30]

Diğer Faydalı Metotlar

* join: Dizinin elemanlarını belirli bir ayırıcı ile birleştirerek bir string oluşturur.

kelimeler = ["Ruby", "dizileri", "harika!"]
    cumle = kelimeler.join(" ") # "Ruby dizileri harika!"

* zip: Bir diziyi, diğer dizilerin aynı indeksteki elemanlarıyla birleştirerek yeni dizilerden oluşan bir dizi oluşturur.

dizi_a = [1, 2, 3]
    dizi_b = [:a, :b, :c]
    dizi_c = ["x", "y", "z"]
    birlesik = dizi_a.zip(dizi_b, dizi_c)
    # [[1, :a, "x"], [2, :b, "y"], [3, :c, "z"]]

* product: İki veya daha fazla dizinin Kartezyen çarpımını hesaplar.

renkler = ["kırmızı", "mavi"]
    bedenler = ["S", "M", "L"]
    kombinasyonlar = renkler.product(bedenler)
    # [["kırmızı", "S"], ["kırmızı", "M"], ["kırmızı", "L"],
    #  ["mavi", "S"], ["mavi", "M"], ["mavi", "L"]]

* sample: Diziden rastgele bir veya N adet eleman seçer.

dizi = [1, 2, 3, 4, 5]
    rastgele_eleman = dizi.sample # Rastgele bir eleman
    rastgele_iki_eleman = dizi.sample(2) # Rastgele iki eleman

İç İçe Diziler (Çok Boyutlu Diziler)

Ruby'de iç içe diziler, bir dizinin elemanlarının başka diziler olması durumudur. Bu yapı, matrisler veya tablolardaki verileri temsil etmek için yaygın olarak kullanılır.

matris = [
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
]

* Elemanlara Erişim: İki indeks kullanarak erişilir: ilki dış dizideki satır indeksi, ikincisi ise iç dizideki sütun indeksi.

puts matris[0][0] # 1
    puts matris[1][2] # 6

* İç içe diziler üzerinde yineleme:

matris.each do |satir|
      satir.each do |eleman|
        print "#{eleman} "
      end
      puts # Her satır sonunda yeni satıra geç
    end
    # Çıktı:
    # 1 2 3
    # 4 5 6
    # 7 8 9

İç içe diziler, karmaşık veri yapılarını düzenli bir şekilde tutmak için güçlü bir mekanizma sunar.

Performans İpuçları ve En İyi Uygulamalar

Ruby'nin esnekliği bazen performans maliyetleriyle gelebilir. Dizilerle çalışırken verimliliği artırmak ve kodu daha iyi hale getirmek için bazı ipuçları:

* Doğru Metodu Seçin: Her görev için en uygun metodu kullanmak performansı artırır. Örneğin, bir elemanı dönüştürüp yeni bir dizi oluşturacaksanız map kullanın. Sadece yan etki için (ekrana yazdırma gibi) yineleyecekseniz each kullanın. Koşullu seçimler için select veya reject tercih edin.
* Zincirleme Metotlar (Method Chaining): Ruby'nin Enumerable modülü sayesinde birçok dizi metodu zincirleme olarak kullanılabilir. Bu, kodu daha okunabilir ve akıcı hale getirir. Ancak, her adımda yeni bir dizi oluşturulabileceği için büyük dizilerde dikkatli olunmalıdır.

sayilar = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    sonuc = sayilar.select(&:even?).map { |n| n * 10 }.sum
    # Önce çift sayıları seç, sonra her birini 10 ile çarp, sonra topla.

* Büyük Dizilerle Çalışırken Dikkatli Olun: Özellikle map, select gibi yeni diziler döndüren metotlar, büyük dizilerle çalışırken bellek tüketimini artırabilir. Eğer sadece bir kez yineleme yapıp büyük bir ara dizi oluşturmaktan kaçınmak istiyorsanız, Enumerator ve lazy metodu faydalı olabilir.

(1..Float::INFINITY).lazy.select(&:even?).map { |n| n * 10 }.first(5).to_a
    # Sonsuz bir aralık üzerinde tembel (lazy) hesaplama yaparak ilk 5 elemanı bulur.
    # Tüm aralığı belleğe yüklemez.

* Yerinde Değişiklikler (!) ve Yan Etkiler: sort!, reverse!, uniq! gibi sonu ! ile biten metotlar, orijinal diziyi yerinde değiştirir. Bu, bellek açısından daha verimli olabilir ancak beklenmedik yan etkilere neden olabileceği için dikkatli kullanılmalıdır, özellikle aynı diziye birden fazla referans varsa.
* İndeks Erişimi vs. Yineleme: Belirli bir indekse hızlı erişim gerektiğinde [] veya at() kullanın. Ancak, tüm elemanlar üzerinde işlem yapmanız gerekiyorsa yineleme metotları (each, map vb.) genellikle daha okunabilir ve idiomatiktir.

Sonuç

Ruby'deki diziler, programlama dünyasında veri depolama ve işleme için vazgeçilmez bir araçtır. Bu makalede, dizilerin nasıl oluşturulduğundan, elemanlarına nasıl erişildiğinden, eklendiğinden ve çıkarıldığından bahsettik. Ayrıca, each, map, select, reduce gibi güçlü yineleme metotları ile diziler üzerinde nasıl dönüşümler yapılabileceğini detaylandırdık. sort, uniq, flatten, join gibi manipülasyon metotları ve iç içe dizilerin kullanımı da ele alındı. Son olarak, performans ipuçları ve en iyi uygulamalarla Ruby'de dizilerle daha verimli çalışmanın yollarını gösterdik.

Ruby'nin zengin Array ve Enumerable metotları, karmaşık veri işleme görevlerini kısa, okunabilir ve etkili kodlarla çözmenizi sağlar. Bu metotları ustaca kullanmak, Ruby programlama yeteneklerinizi önemli ölçüde geliştirecek ve daha temiz, daha sürdürülebilir uygulamalar yazmanıza yardımcı olacaktır. Dizilerle çalışırken denemekten ve farklı metot kombinasyonlarını keşfetmekten çekinmeyin; Ruby'nin gücü, size sunduğu bu esneklikte yatmaktadır.

Yorumlar
İçeriği beğendiniz mi? Bir tartışma başlatın veya görüşlerinizi paylaşın.
Yorum Yaz

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Gönder

E-posta Bülteni
Yazılım Topluluğuna Katılın
En son güncellemeleri, yaratıcı ipuçlarını ve özel kaynakları doğrudan e-posta kutunuza alın. Tasarım ve inovasyonun geleceğini birlikte keşfedelim.
Exit mobile version