Soru Ruby'de string düzleştirme


Anahtar ve değer çiftleri ve anahtar / değer çiftleri arasında isteğe bağlı sınırlayıcılar ile bir karma bir dizeyi düzleştirmek için bir yolu var mı?

Örneğin, print {:a => :b, :c => :d}.flatten('=','&') yazdırmalı a=b&c=d

Bunu yapmak için bazı kod yazdım, ama daha iyi bir yol olup olmadığını merak ediyordum:

class Hash
  def flatten(keyvaldelimiter, entrydelimiter)
    string = ""
    self.each do
      |key, value|
      key = "#{entrydelimiter}#{key}" if string != "" #nasty hack
      string += "#{key}#{keyvaldelimiter}#{value}"  
    end
    return string
  end
end

print {:a => :b, :c => :d}.flatten('=','&') #=> 'c=d&a=b'

Teşekkürler


44
2018-06-15 16:17


Menşei




Cevaplar:


Ben geçersiz olmaz .flattenzaten tanımlanmış olan:

Bir olan yeni bir dizi döndürür   bunun tek boyutlu düzleştirilmesi   karması. Yani, her anahtar veya değer için   Bu bir dizi, öğelerini ayıkla   yeni diziye. aksine   Array # flatten, bu yöntem   varsayılan olarak art arda düzleştirilir. Eğer   İsteğe bağlı seviye argümanı belirler   düzeltmek için yineleme seviyesi.

Bunu bildiğim en basit yol budur:

{:a => 100, :b => 200}.map{|k,v| "#{k}=#{v}"}.join('&')
# => "a=100&b=200"

98
2018-06-15 16:33



Bunu daha da basitleştirebilirsiniz. Detaylar için cevabımı görün. Özü değiştirmek |k, v| ile |e| hangi yapar e arayabileceğiniz bir dizi e.join('=') üzerinde. - Jörg W Mittag
karma almak için tersi nasıl yapılır - januprasad


@ Elektronaut'un versiyonunun hafif değişimi:

Aslında sadece bir |e| yerine |k, v| bu durumda e iki elemandan oluşan bir dizidir ve e.join('='). Tamamen senin gibi bir şey var

class Hash
  def join(keyvaldelim=$,, entrydelim=$,) # $, is the global default delimiter
    map {|e| e.join(keyvaldelim) }.join(entrydelim)
  end
end

{a: 100, b: 200}.join('=', '&') # I love showing off the new Ruby 1.9 Hash syntax
# => 'a=100&b=200'

22
2018-06-15 18:31



Maymun yama için ne kadar zeki olduğunu ciddi olarak sorgularım Hashözellikle isimsiz bir yöntem adı gibi join. Bunu birçoğundan beklerken çok deneyimli bir devinden böyle bir öneri görmekten çok şaşırdım. - akostadinov


Peki, standart yöntemler ve dizilerle yapabilirsin:

class Hash
  def flatten(keyvaldelimiter, entrydelimiter)
    self.map { |k, v| "#{k}#{keyvaldelimiter}#{v}" }.join(entrydelimiter)
  end
end

Ayrıca ilginizi çekebilir Raylar to_query yöntem.

Ayrıca, açıkça yazabilirsiniz. "#{k}#{keyvaldelimiter}#{v}" gibi k.to_s + keyvaldelimiter + v.to_s...


5
2018-06-15 16:27



Veya [k,v].join(keyvaldelimiter). - henrikhodne


Bir URL sorgu dizesi oluşturmaya çalışıyorsanız, kesinlikle activesupport'un to_param (to_query ile aynı adlı) gibi bir yöntemi kullanmalısınız. Verilerin kendisinde bir işareti veya eşit işareti varsa, sorunları hayal edin.

to_query kaçmakla ilgilenir:

>> require 'active_support/core_ext/object'
>> {'a&' => 'b', 'c' => 'd'}.to_query
>> => "a%26=b&c=d"

DÜZENLE

@fahadsadah, Rails yüklemek istememekle ilgili iyi bir noktaya işaret ediyor. Active_support / core_ext / object bile 71 dosya yükleyecektir. Aynı zamanda maymun-yamalar çekirdek sınıfları.

Hafif ve temiz bir çözüm:

require 'rack'  # only loads 3 files
{'a&' => 'b', 'c' => 'd'}.map{|pair|
  pair.map{|e| Rack::Utils.escape(e.to_s) }.join('=')
}.join('&')
# => "a%26=b&c=d"

Kaçmak önemlidir, aksi halde operasyon geri dönüşlü değildir.


4
2018-03-20 18:27



Hepsi çok iyi ve iyi bir nokta, ancak kaynak karmasını oluşturduğumda Rails'in yüklenmesini istemem. - Fahad Sadah
Kazanmak için raylar !! - Joshua Pinter


Yerleşik bir yol olup olmadığından emin değilsiniz, ancak burada bazı kısa kodlar:

class Hash
  def flatten(kvdelim='', entrydelim='')
    self.inject([]) { |a, b| a << b.join(kvdelim) }.join(entrydelim)
  end
end

puts ({ :a => :b, :c => :d }).flatten('=', '&') # => a=b&c=d

1
2018-06-15 16:27





JSON biçiminde almayı ne dersiniz? Bu şekilde format açıktır.

Yakut için çok sayıda JSON aracı var. Yine de onları denemedim. Ancak çıktı elbette javascript'e, vb. Muhtemelen bir satır.

Büyük tasarruflar, dokümantasyonda olsa da, daha azına ihtiyacınız olacak.


0
2018-06-15 20:24