복붙노트

[RUBY-ON-RAILS] 어떻게 루비 배열에서 평균을 만들려면 어떻게해야합니까?

RUBY-ON-RAILS

어떻게 루비 배열에서 평균을 만들려면 어떻게해야합니까?

어떻게 배열의 평균을 찾을 얻을 것?

나는 배열이있는 경우 :

[0,4,8,2,5,0,2,6]

평균화는 나에게 3.375을 줄 것입니다.

해결법

  1. ==============================

    1.이 시도:

    이 시도:

    arr = [5, 6, 7, 8]
    arr.inject{ |sum, el| sum + el }.to_f / arr.size
    => 6.5
    

    당신은 정수 나누기에서 어떤 문제를 방지 원하는거야 .to_f을합니다. 당신은 또한 할 수 있습니다 :

    arr = [5, 6, 7, 8]
    arr.inject(0.0) { |sum, el| sum + el } / arr.size
    => 6.5
    

    다른 주석이 제안한대로 배열의 일부로 정의 할 수 있습니다,하지만 당신은 분열의 정수 방지하기 위해 필요하거나 결과가 잘못 될 것입니다. 또한, 이것은 일반적으로 가능한 모든 요소 유형 (분명히, 평균은 평균 할 수있는 일에 대한 의미가) 적용되지 않습니다. 당신은 그 길을 가고 싶어하지만, 이것을 사용 :

    class Array
      def sum
        inject(0.0) { |result, el| result + el }
      end
    
      def mean 
        sum / size
      end
    end
    

    이전에 분사 보지 못한 경우가 나타날 수 있습니다, 그것은 같은 마법이 아니다. 각 요소로 반복 한 다음에 누산기 값을 적용한다. 어큐뮬레이터는 그 다음 요소로 넘겨진다. 이 경우, 우리의 축적은 단순히 이전의 모든 요소의 합을 반영하는 정수입니다.

    편집 : 주석 기 데이브 레이는 좋은 개선을 제안했다.

    편집 : 주석 기 글렌 잭맨의 제안, arr.inject를 사용하여 (+). 당신이 무슨 일인지 모르는 경우 to_f는 너무 그러나 아마 조금 너무 영리 좋다. : +는 상징이다; 주입 통과 할 때, 누산기 값에 대해 각각의 요소에 대한 기호라는 방법 (이 경우, 가산 동작)을 적용한다.

  2. ==============================

    2.

    a = [0,4,8,2,5,0,2,6]
    a.instance_eval { reduce(:+) / size.to_f } #=> 3.375
    

    instance_eval 사용하지 않는이의 버전은 다음과 같습니다

    a = [0,4,8,2,5,0,2,6]
    a.reduce(:+) / a.size.to_f #=> 3.375
    
  3. ==============================

    3.내가 가장 간단한 대답은 생각

    내가 가장 간단한 대답은 생각

    list.reduce(:+).to_f / list.size
    
  4. ==============================

    4.나는 Math.average (값),하지만 그런 행운을 기대했다.

    나는 Math.average (값),하지만 그런 행운을 기대했다.

    values = [0,4,8,2,5,0,2,6]
    average = values.sum / values.size.to_f
    
  5. ==============================

    5.루비 버전> = 2.4 열거 가능한 # 합 방법이있다.

    루비 버전> = 2.4 열거 가능한 # 합 방법이있다.

    그리고 점의 평균을 떠 얻을, 당신은 정수 #의 FDIV을 사용할 수 있습니다

    arr = [0,4,8,2,5,0,2,6]
    
    arr.sum.fdiv(arr.size)
    # => 3.375
    

    이전 버전의 경우 :

    arr.reduce(:+).fdiv(arr.size)
    # => 3.375
    
  6. ==============================

    6.일부 (가장 효율적인 순서) 최고 솔루션의 벤치마킹 :

    일부 (가장 효율적인 순서) 최고 솔루션의 벤치마킹 :

    array = (1..10_000_000).to_a
    
    Benchmark.bm do |bm|
      bm.report { array.instance_eval { reduce(:+) / size.to_f } }
      bm.report { array.sum.fdiv(array.size) }
      bm.report { array.sum / array.size.to_f }
      bm.report { array.reduce(:+).to_f / array.size }
      bm.report { array.reduce(:+).try(:to_f).try(:/, array.size) }
      bm.report { array.inject(0.0) { |sum, el| sum + el }.to_f / array.size }
      bm.report { array.reduce([ 0.0, 0 ]) { |(s, c), e| [ s + e, c + 1 ] }.reduce(:/) }
    end
    
    
        user     system      total        real
    0.480000   0.000000   0.480000   (0.473920)
    0.500000   0.000000   0.500000   (0.502158)
    0.500000   0.000000   0.500000   (0.508075)
    0.510000   0.000000   0.510000   (0.512600)
    0.520000   0.000000   0.520000   (0.516096)
    0.760000   0.000000   0.760000   (0.767743)
    1.530000   0.000000   1.530000   (1.534404)
    
    array = Array.new(10) { rand(0.5..2.0) }
    
    Benchmark.bm do |bm|
      bm.report { 1_000_000.times { array.reduce(:+).to_f / array.size } }
      bm.report { 1_000_000.times { array.sum / array.size.to_f } }
      bm.report { 1_000_000.times { array.sum.fdiv(array.size) } }
      bm.report { 1_000_000.times { array.inject(0.0) { |sum, el| sum + el }.to_f / array.size } }
      bm.report { 1_000_000.times { array.instance_eval { reduce(:+) / size.to_f } } }
      bm.report { 1_000_000.times { array.reduce(:+).try(:to_f).try(:/, array.size) } }
      bm.report { 1_000_000.times { array.reduce([ 0.0, 0 ]) { |(s, c), e| [ s + e, c + 1 ] }.reduce(:/) } }
    end
    
    
        user     system      total        real
    0.760000   0.000000   0.760000   (0.760353)
    0.870000   0.000000   0.870000   (0.876087)
    0.900000   0.000000   0.900000   (0.901102)
    0.920000   0.000000   0.920000   (0.920888)
    0.950000   0.000000   0.950000   (0.952842)
    1.690000   0.000000   1.690000   (1.694117)
    1.840000   0.010000   1.850000   (1.845623)
    
  7. ==============================

    7.

    class Array
      def sum 
        inject( nil ) { |sum,x| sum ? sum+x : x }
      end
    
      def mean 
        sum.to_f / size.to_f
      end
    end
    
    [0,4,8,2,5,0,2,6].mean
    
  8. ==============================

    8.제가 제로 문제의 분할을 해결 경쟁에 무언가를 가져 보자 :

    제가 제로 문제의 분할을 해결 경쟁에 무언가를 가져 보자 :

    a = [1,2,3,4,5,6,7,8]
    a.reduce(:+).try(:to_f).try(:/,a.size) #==> 4.5
    
    a = []
    a.reduce(:+).try(:to_f).try(:/,a.size) #==> nil
    

    나는 "노력"레일 도우미 있다는 점을 인정해야합니다. 하지만 당신은 쉽게 해결할 수 있습니다 :

    class Object;def try(*options);self&&send(*options);end;end
    class Array;def avg;reduce(:+).try(:to_f).try(:/,size);end;end
    

    BTW : 나는 빈리스트의 평균이 전무는 것을 올바른 생각합니다. 아무것도의 평균은 예상되는 동작하지 0 그래서 아무것도 아니다. 그러나, 당신은에 변경하는 경우 :

    class Array;def avg;reduce(0.0,:+).try(:/,size);end;end
    

    빈 배열에 대한 결과는 내가 예상했던대로 예외가되지 않지만 대신이 NaN을 반환 ... 나는 본 적이 없어 그 루비 전에. ;-)는 Float 클래스의 특별 행동이 될 것 같습니다 ...

    0.0/0 #==> NaN
    0.1/0 #==> Infinity
    0.0.class #==> Float
    
  9. ==============================

    9.내가이 허용 솔루션에 대해 좋아하지 않는다

    내가이 허용 솔루션에 대해 좋아하지 않는다

    arr = [5, 6, 7, 8]
    arr.inject{ |sum, el| sum + el }.to_f / arr.size
    => 6.5
    

    정말 순수하게 기능적인 방식으로 작동하지 않습니다. 우리는 마지막에 계산 arr.size에 변수 편곡이 필요합니다.

    순전히 기능적으로이 문제를 해결하기 위해 우리는 두 추적 할 필요 값 : 모든 요소들의 합, 및 소자의 수.

    [5, 6, 7, 8].inject([0.0,0]) do |r,ele|
        [ r[0]+ele, r[1]+1 ]
    end.inject(:/)
    => 6.5   
    

    Santhosh이 솔루션에 개선 : 인수 r은 배열되는 대신에, 우리는 immediatly 두 변수로 떨어져를 선택하는 destructuring 사용할 수 있습니다

    [5, 6, 7, 8].inject([0.0,0]) do |(sum, size), ele| 
       [ sum + ele, size + 1 ]
    end.inject(:/)
    

    당신이 어떻게 작동하는지보고 싶다면, 일부 풋를 추가 :

    [5, 6, 7, 8].inject([0.0,0]) do |(sum, size), ele| 
       r2 = [ sum + ele, size + 1 ]
       puts "adding #{ele} gives #{r2}"
       r2
    end.inject(:/)
    
    adding 5 gives [5.0, 1]
    adding 6 gives [11.0, 2]
    adding 7 gives [18.0, 3]
    adding 8 gives [26.0, 4]
    => 6.5
    

    우리는 또한 합계 수를 포함하는 배열 대신 구조체를 사용할 수 있지만 우리는 먼저 구조체를 선언해야합니다 :

    R=Struct.new(:sum, :count)
    [5, 6, 7, 8].inject( R.new(0.0, 0) ) do |r,ele|
        r.sum += ele
        r.count += 1
        r
    end.inject(:/)
    
  10. ==============================

    10.공공 오락, 또 다른 솔루션 :

    공공 오락, 또 다른 솔루션 :

    a = 0, 4, 8, 2, 5, 0, 2, 6
    a.reduce [ 0.0, 0 ] do |(s, c), e| [ s + e, c + 1 ] end.reduce :/
    #=> 3.375
    
  11. ==============================

    11.이 PC에서 루비 필요는 없지만,이 정도 뭔가 작업을해야합니다 :

    이 PC에서 루비 필요는 없지만,이 정도 뭔가 작업을해야합니다 :

    values = [0,4,8,2,5,0,2,6]
    total = 0.0
    values.each do |val|
     total += val
    end
    
    average = total/values.size
    
  12. ==============================

    12.나는 그냥 단순 평균 방식으로 배열 클래스를 확장하는 신중한라고 생각 때문에 자주 같은 일을하고 있었다. 그것은 정수 또는 수레 또는 소수와 같은 숫자의 배열 외에 아무것도 일을하지 않습니다하지만 당신이 바로 그것을 사용할 때 편리합니다.

    나는 그냥 단순 평균 방식으로 배열 클래스를 확장하는 신중한라고 생각 때문에 자주 같은 일을하고 있었다. 그것은 정수 또는 수레 또는 소수와 같은 숫자의 배열 외에 아무것도 일을하지 않습니다하지만 당신이 바로 그것을 사용할 때 편리합니다.

    내가 배치했습니다, 그래서 나는 레일에있는 설정 / 초기화 / array.rb하지만 당신은 어디에서나 배치 할 수있는 부팅에 포함의 등 루비를 사용하고 있습니다

    설정 / 초기화 / array.rb

    class Array
    
      # Will only work for an Array of numbers like Integers, Floats or Decimals.
      #
      # Throws various errors when trying to call it on an Array of other types, like Strings.
      # Returns nil for an empty Array.
      #
      def average
        return nil if self.empty?
    
        self.sum / self.size
      end
    
    end
    
  13. ==============================

    13.

    a = [0,4,8,2,5,0,2,6]
    sum = 0
    a.each { |b| sum += b }
    average = sum / a.length
    
  14. ==============================

    14.

    a = [0,4,8,2,5,0,2,6]
    a.empty? ? nil : a.reduce(:+)/a.size.to_f
    => 3.375
    

    해결이 부문의 정수, 0으로 나누어 읽기 쉬운. 당신이 하늘의 배열을 반환 0을 선택하면 쉽게 수정할 수 있습니다.

    너무이 변형 같은 I,하지만 조금 더 장황입니다.

    a = [0,4,8,2,5,0,2,6]
    a.empty? ? nil : [a.reduce(:+), a.size.to_f].reduce(:/)
    => 3.375
    
  15. ==============================

    15.이 방법은 도움이 될 수 있습니다.

    이 방법은 도움이 될 수 있습니다.

    def avg(arr)
      val = 0.0
    
      arr.each do |n|
        val += n
        end
    
      len = arr.length
    
      val / len 
    end
    
    p avg([0,4,8,2,5,0,2,6])
    
  16. ==============================

    16.

    arr = [0,4,8,2,5,0,2,6]
    average = arr.inject(&:+).to_f / arr.size
    # => 3.375
    
  17. ==============================

    17.당신은 다음과 같은 것을 시도해 볼 수도 있습니다 :

    당신은 다음과 같은 것을 시도해 볼 수도 있습니다 :

    a = [1,2,3,4,5]
    # => [1, 2, 3, 4, 5]
    (a.sum/a.length).to_f
    # => 3.0
    
  18. ==============================

    18.

    [1,2].tap { |a| @asize = a.size }.inject(:+).to_f/@asize
    

    짧지 만 인스턴스 변수를 사용하여

  19. from https://stackoverflow.com/questions/1341271/how-do-i-create-an-average-from-a-ruby-array by cc-by-sa and MIT license