红宝石中的哈希减法

时间:2017-07-13 18:27:05

标签: ruby-on-rails ruby

我有2个哈希值(稍后将转换为数组,不确定这是否相关):

Hash1 = {"X"=>2, "Y"=>1, "Z"=>1}

Hash2 = {"X"=>1, "Y"=>1}

我需要减去它们(Hash3 = Hash1 - Hash2),我需要Hash3的结果,在这种情况下:

Hash3 = {"X"=>1, "Y"=>0, "Z"=>1}

我见过的所有示例和答案都会导致结果,其中值得等于0(Y)的键在结果哈希中不存在,这不是我需要的。

我使用的是Ruby 2.3.3和Rails 5.0

3 个答案:

答案 0 :(得分:12)

你可以merge他们:

h1 = {"X"=>2, "Y"=>1, "Z"=>1}
h2 = {"X"=>1, "Y"=>1}

h1.merge(h2) { |k, v1, v2| v1 - v2 }
#=> {"X"=>1, "Y"=>0, "Z"=>1}

每当两个哈希中都存在一个键时,就会调用该块来确定新值。

由于此行为,如果某个密钥仅出现在h2中,则会导致负值:

h1 = {"X"=>2, "Y"=>1}
h2 = {"X"=>1, "Y"=>1, "Z"=>1}

h1.merge(h2) { |k, v1, v2| v1 - v2 }
#=> {"X"=>1, "Y"=>0, "Z"=>1}

你可能期望:

#=> {"X"=>1, "Y"=>0, "Z"=>-1}

tadman's solution将返回的是什么。

答案 1 :(得分:3)

如果将其分解为两个步骤并不太难:

def hash_sub(a, b)
  (a.keys + b.keys).uniq.map do |k|
    [ k, a[k].to_i - b[k].to_i ]
  end.to_h
end

hash_sub({"X"=>2, "Y"=>1, "Z"=>1}, {"X"=>1, "Y"=>1})
# => {"X"=>1, "Y"=>0, "Z"=>1}

第一步是通过组合两个哈希中的键来计算所有可能的(唯一)键,然后通过从另一个中减去一个来转换为新哈希,强制转换为.to_i的整数

答案 2 :(得分:0)

您也可以映射它们(但合并解决方案更好,因为即使1中没有键,它也会照顾到2中的值):

private void PageLoad(object sender, System.EventArgs e)
{
    System.IO.MemoryStream mstream = createDocument();
    byte[] byteArray = mstream.ToArray();
    mstream.Flush();
    mstream.Close();
    Response.Clear();
    // Add a HTTP header to the output stream that specifies the default filename
    // for the browser's download dialog
    Response.AddHeader("Content", "attachment; filename=foo.docx");
    // Add a HTTP header to the output stream that contains the 
    // content length(File Size). This lets the browser know how much data is being transfered
    Response.AddHeader("Content", byteArray.Length.ToString());
    // Set the HTTP MIME type of the output stream
    Response.ContentType = "application/octet-stream";
    // Write the data out to the client.
    Response.BinaryWrite(byteArray);
}

这将产生一个数组