2013-01-05 18 views
8

Czy ktoś może mi pomóc skrócić następującą metodę? Zacząłem od tego, co mi się bardzo podobało:Warunkowe uwzględnienie pary klucz-wartość w haszcie

def self.some_hash 
    { "foo" => "bar" } 
end 

Teraz chcę dodać opcjonalny klucz. Tersest składnia mogę myśleć to:

def self.some_hash(some_key=nil) 
    answer = { "foo" => "bar" } 
    answer[some_key] = "yucky, long-winded syntax" if some_key 
    answer 
end 

Zmodyfikowana metoda działa, ale jestem niezadowolony z odpadami wirtualnego atramentu. Czy istnieje sposób, aby to skrócić? Zdaję sobie sprawę, że można użyć operatora trójskładnikowego na literałowym haśle, ale to wymusiłoby (jak sądzę) powtórzenie pary na każdym odgałęzieniu warunku, który również jest nieco mniejszy niż pierwotny.

+0

"pomóżcie mi skrócić następującą metodę" to rozdawanie że powinno to być na codereview.stackexchange.com, gdzie robią opinie i pomagają w refaktoryzacji i optymalizacji. –

+0

Smutno, że to pytanie zostało zamknięte, kiedy naprawdę pyta: "W jaki sposób warunkowo dołączyć parę klucz/wartość w haszyszu?". Napisałem odpowiedź w innym miejscu, korzystając z [podwójnego operatora] Ruby 2.0 (http://stackoverflow.com/a/37474217/122087). –

+0

@PaulAJungwirth, domyślam się, że został zamknięty, ponieważ chciałem tylko poprawić działający kod. Mogłem zamiast tego wymyślić trochę składni śmieci, a następnie stwierdziłem, że to nie działa, a wszystko będzie dobrze w SO. To WIELKA wskazówka na temat operatora **! Dzięki <--- zniechęcanie 'dzięki w komentarzu jest kolejną głupią, normą tutaj, ale -> DZIĘKI! – danh

Odpowiedz

8
def self.some_hash(some_key = nil) 
    {"foo" => "bar"}.merge(some_key ? {some_key => "yucky, long-winded syntax"} : {}) 
end 

Lub, jeśli modyfikowania oryginalnego hash,

def self.some_hash(some_key = nil) 
    {"foo" => "bar"} 
    .tap{|h| h.merge!(some_key => "yucky, long-winded syntax") if some_key} 
end 

Albo, może to zrobić w taki sposób, blisko oryginalny:

def self.some_hash(some_key = nil) 
    {"foo" => "bar"} 
    .tap{|h| h[some_key] = "yucky, long-winded syntax" if some_key} 
end 
+1

Oh. To naprawdę miłe. Krótkie, jak @Kyle, i wyraźniejsze. Również dobre, ponieważ zawiera, a nie usuwa, warunkowo. Dzięki. – danh

+0

+1 za pierwszy (funkcjonalny) fragment, pozostałbym tak daleko od 'tap', jak to tylko możliwe (IMHO promuje imperatywny, niejasny kod) – tokland

+0

dzięki. również doceniaj uczenie się o .tap. Meta pytanie: dzięki za edytowanie moje pytanie. czy jest jakiś krok, który muszę podjąć, aby zaakceptować edycję? – danh

1

naprawdę nie podoba, ale to jest dość lakoniczny (i mylące)

def self.some_hash(some_key=nil) 
    Hash[[["foo", "bar"], [some_key, "some value"]].select(&:first)] 
end 

To może być trochę lepiej.

def self.some_hash(some_key=nil) 
    {"foo" => "bar", some_key => "some_value"}.keep_if{ |k, _| k } 
end 

Hash#keep_if

+0

Dzięki. To co najmniej +1 za zwięzłość. Poczeka trochę, aby zobaczyć, co jeszcze zasugerowano. – danh

+0

@danh Dodałem jeszcze jeden dla ciebie, który moim zdaniem jest trochę lepszy. – Kyle

+0

Chciałbym móc dwukrotnie głosować w górę. Myślę, że twoja druga idea jest bardziej przejrzysta i krótka, ale @sawa ratuje nas przed dodaniem + warunkowego usunięcia. Nigdy nie słyszałem o keep_if i doceniam to również! – danh