2011-03-06 6 views
8

배열에서 가장 긴 단어를 찾기 위해이 방법을 만들었지 만, 더 좋은 방법이 있는지 궁금합니다. Ruby를 처음 접했을 때 inject 메서드를 배우기위한 연습으로이 작업을 수행했습니다.배열에서 Ruby가 가장 긴 단어

배열에서 가장 긴 단어 또는 동등한 가장 긴 단어의 배열을 반환합니다.

답변

27

내가 할 것

class Array 
    def longest_word 
    group_by(&:size).max.last 
    end 
end 
+1

문자열 만 가지고 있다면'self.group_by (& length) .max.last'라고 쓸 수 있습니다. 그렇지 않으면'self_group_by {| el | el.to_s '와 같은 추가'to_s' 호출이 필요합니다. .size} .max.last'. 마지막으로, 하나의 요소 만 가질 때 단일 문자열을 반환하려면'longest_word.size> 1을 할 수 있습니까? longest_word : longest_word.first'를 반환합니다. –

+0

니스! 나는 코드를 더 간결하게 만들었지 만, 스타일이 마음에 들지 않는다면 되돌려주세요. –

+0

OP는 그가 주사를 배우기 위해 이것을했다고 질문하면서 그가 찾고 있는지 여부는 분명하지 않습니다. 'inject' 또는 더 나은 방법으로 사용하는 것이 더 좋습니다. 너의 것은 두 번째 해석에 대한 꽤 좋은 대답이고, @Mladen Jablanović의 첫 번째 해석이다. 둘 다 내 +1을 얻습니다. –

6

루비에는 최대 값을 가진 목록의 요소를 반환하는 표준 방법이 있습니다.

anArray.max{|a, b| a.length <=> b.length} 

하거나 최대 길이 모든 요소를 ​​얻기 위해 max_by 방법

anArray.max_by(&:length) 

을 사용할 수 있습니다

max_length = anArray.max_by(&:length).length 
all_with_max_length = anArray.find_all{|x| x.length = max_length} 
+0

하지만, OP ". 바로 분사 방법을 학습을위한 연습으로 이런 짓을" –

+3

두 메서드는 모두 동일한 길이의 문자열 배열이 아닌 단일 요소 만 반환합니다. –

1

두 라이너 :

vc = ['asd','s','1234','1235'].sort{|a,b| b.size <=> a.size} 
vc.delete_if{|a| a.size < vc.first.size} 


#Output 
["1235", "1234"] 

경우 또는 당신은 주사를 사용하기를 원한다. 이것은 당신의 아이디어를 사용하지만, 광석 부족.

test_array.inject{ |ret,word| 
    ret = [ret] unless ret.kind_of?(Array) 

    ret << word if word.size == ret.first.size 
    ret = [word] if word.size > ret.first.size 
    ret 
} 
+0

이 방법은 배열에 직접 적용 할 때 멱급수가 아닙니다. 아마도 당신이 기대하는 것만은 아닙니다. 여기서 '복제본'을 사용할 수 있습니다.그러나 해결책은 괜찮습니다. 그리고 가장 느리지는 않습니다. (group_by 내장 메소드의 구현 세부 사항을 모른 채로) –

+1

@Holger :'group_by'는 배열 조회를 사용하기 때문에 기본적으로'O (n)'입니다. 'sort'는 더 느립니다. –

+0

'delete_if '대신'take_while'를 사용하면 더 작은 단어에 도달하자마자 멈출 수 있습니다. –

1
이 방법은 일반적인 Enumerable 방법에 따라 달라집니다
module Enumerable 
    def longest_word 
    (strings = map(&:to_s)). 
     zip(strings.map(&:length)). 
     inject([[''],0]) {|(wws, ll), (w, l)| 
     case l <=> ll 
     when -1 then [wws, ll] 
     when 1 then [[w], l] 
     else   [wws + [w], ll] 
     end 
     }.first 
    end 
end 

는, 따라서 우리는 또한 Set의 또는 Enumerator의 사용할 수있을 것 Enumerable 모듈로를 당길 수, 그것에 대해 특정 아무것도 Array 없다 뿐만 아니라 s.

+0

동일한 크기의 단어 배열이 아닌 하나의 요소 만 반환합니다. – steenslag

+0

@steenslag : 알았어, 고마워. 메서드 이름이 조금 벗어났습니다. 여러 단어를 'longest_words'(복수형)로 반환하는 메서드가 필요할 것입니다. –

4

여기 inject를 사용하여 하나가 (하늘의 배열 작동하지 않습니다)입니다 : 사람들을 위해

words.inject(['']){|a,w| 
    [a + [w], [w], a][w.length <=> a.last.length] 
} 

로 단축 할 수

words.inject(['']){|a,w| 
    case w.length <=> a.last.length 
    when -1 
    a 
    when 0 
    a << w 
    when 1 
    [w] 
    end 
} 

골프를 좋아하는 사람.

+0

사실, 이것은 * 누적 기의 초기 값을 명시 적으로 제공하는 점 중 하나입니다 (빈 배열에 대해 * 작동해야 함). –

+0

제 버전에서는 어쨌든 누적기를 통해 단어 길이를 암기 적으로 처리하는 것이 훨씬 더 깔끔할 것이라고 생각 했었지만 정확하게 정리하지는 못했습니다 :-) 당신 것이 훨씬 멋지게 보입니다. –

+0

빈 배열에 대해 작업하려면 빈 배열을 사용하여'inject'를 킥 스타트해야합니다 (빈 문자열을 포함하는 배열이 아니라). 조금 더 복잡해지면 분기가 복잡해집니다. 그러나'주사하다 '를 배우려는 목적으로는 충분하다고 생각했습니다. –

0

이 솔루션은 주사 방법을 사용하여 가장 긴 문자열을 배열에 축적 한 다음 가장 긴 길이의 문자열을 선택합니다.

동물 = [ "마우스", "고양이", "새", "사슴"을 "부담"]

animals.inject (Hash.new {| H, K | H [K] = [ ]}) {| acc, e | acc [e.size] < < e; ACC는} .sort.last [1]

이 반환 : [ "마우스", "마우스"] 좋다

관련 문제