Scale an Array to min/max

时间:2017-08-30 20:49:50

标签: ruby-on-rails ruby

In Ruby, given the following array

label

How would I go about getting a result like the following where there is a min of 0, and a max of 100. (this result is a guess, and not an actual reflection of what the numbers should look like)

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="xml" omit-xml-declaration="yes" indent="yes" />
  <xsl:strip-space elements="*"/>

  <xsl:template match="/">
    <table cellspacing="0" cellpadding="0"><tbody>
      <xsl:for-each-group select="*/nearme/location" group-by="floor((position() - 1) div 5)">
        <tr>
        <xsl:for-each select="current-group()">
          <td>
          <input type="radio" name="rf" id="rf" class="page_checkbox"/>
            <label for="rf1"><span><xsl:value-of select="."/></span></label>
          </td>
        </xsl:for-each>
        </tr>
      </xsl:for-each-group>
    </tbody></table>
  </xsl:template>
</xsl:stylesheet>

note: that the numbers in the middle also scale to fit.

3 个答案:

答案 0 :(得分:3)

这是一个简单的方法:

def normalize(list, scale = 100)
  return unless (list.length >= 2)

  min, max = list.minmax

  range = max - min

  list.map do |v|
    ((v - min) * scale / range)
  end
end

这并不会产生与您预期相同的结果,但我无法确定您为什么会期望这些结果,因为缩放值线性地不会给出这些值。这是一些测试:

list = [-10, 5, 22, 54, 89, 152]

normalize(list)
# => [0, 9, 19, 39, 61, 100]

# Running it again changes nothing
normalize(normalize(list))
# => [0, 9, 19, 39, 61, 100]

list = [-1,0,1]

normalize(list)
# => [0, 50, 100]

答案 1 :(得分:1)

您可以执行以下操作:

ar = [-10, 5, 22, 54, 89, 152]
min = ar.min
range = ar.max - min
res = ar.map do |e|
  ((min - e).to_f / range).abs * 100
end
res
# => [0.0, 9.25925925925926, 19.753086419753085, 39.50617283950617, 61.111111111111114, 100.0]

您可能希望对这些结果进行舍入。

答案 2 :(得分:0)

这是我的方法,我决定移动数组,使第一个元素为0,然后计算出比例:

def scale(a)
  shift = a.first * -1 if a.first != 0 || 0
  a.map! { |n| n + shift }
  return a if a.last == 100
  scale = a.last.to_f / 100.00
  a.map { |n| (n / scale).to_i }
end

puts scale([-10, 5, 22, 54, 89, 152]).inspect
puts scale([-10, 5, 22, 54, 89, 90]).inspect
puts scale([3, 5, 22, 54, 89, 90]).inspect

返回

[0, 9, 19, 39, 61, 100]
[0, 15, 32, 64, 99, 100]
[0, 2, 21, 58, 98, 100]