操作 散列 哈希 ,字典
散列的创建
用字面量进行创建,{}
{键 => 值}或 {键: 值}
使用Hash.new
irb(main):004:0> h1 = Hash.new => {} irb(main):005:0> h2 = Hash.new("ha") => {} irb(main):006:0> h1["not key"] => nil irb(main):007:0> h2["not key"] => "ha" irb(main):008:0>
Hash.new可以穿件没有key情况下的返回值
散列的键可以使用各种对象,不过一般建议使用下面的对象作为散列的键
字符串,数值,符号,日期
值的获取与设定
=> {} irb(main):010:0> h["R"] = irb(main):011:0* "Ruby" => "Ruby" irb(main):012:0> p h["R"] "Ruby" => "Ruby" irb(main):013:0> h => {"R"=>"Ruby"} irb(main):014:0> h.store("P", "Python") => "Python" irb(main):015:0> h["P"] => "Python" irb(main):016:0> h.fetch("p") Traceback (most recent call last): 5: from /usr/bin/irb:23:in `<main>' 4: from /usr/bin/irb:23:in `load' 3: from /Library/Ruby/Gems/2.6.0/gems/irb-1.0.0/exe/irb:11:in `<top (required)>' 2: from (irb):16 1: from (irb):16:in `fetch' KeyError (key not found: "p") Did you mean? "P" irb(main):017:0> h.fetch("P") => "Python" irb(main):018:0> h.fetch("la","moyou") => "moyou" irb(main):019:0> h.fetch("la"){ " meiyou" } => " meiyou" irb(main):020:0> h.fetch("la", String.new) => "" irb(main):021:0>
这里主要是一个fetch,取不到值的情况下,可以取后面的值。
一次性获取所有的键、值
键 .keys 值.values [键_值] .to_a
irb(main):023:0> h = {"a"=>"b", "c"=>"d"} => {"a"=>"b", "c"=>"d"} irb(main):024:0> h.keys => ["a", "c"] irb(main):025:0> h.values => ["b", "d"] irb(main):026:0> h.to_a => [["a", "b"], ["c", "d"]] irb(main):027:0> h.values.clear => [] irb(main):028:0> h => {"a"=>"b", "c"=>"d"} irb(main):029:0>
散列的默认值
.new的值就是散列的默认值,默认是nil
指定生成默认值的块
irb(main):033:0> h = Hash.new do |hash, key| irb(main):034:1* hash[key] = key.upcase irb(main):035:1> end => {} irb(main):036:0> h => {} irb(main):037:0> h["a"] = "aa" => "aa" irb(main):038:0> h["b"] => "B" irb(main):039:0> h["cc"] => "CC" irb(main):040:0>
do 方式,第一参数是hash,第二参数是key
用fetch取值,不收默认值的影响
查看指定对象是否为散列的键或值
查看键
h.key?(key)
h.has_key?(key)
h.include?(key)
h.member?(key)
上面4个方法效果一样的
irb(main):044:0> h => {"a"=>"aa", "b"=>"B", "cc"=>"CC"} irb(main):045:0> h.key?("a") => true irb(main):046:0> h.has_key?("a") => true irb(main):048:0> h.include?("a") => true irb(main):049:0> h.member?("a") => true irb(main):050:0>
查看value在不在用
.value?与.has_value?
查看散列的大小
size length
irb(main):053:0> h => {"a"=>"aa", "b"=>"B", "cc"=>"CC"} irb(main):054:0> h.size => 3 irb(main):055:0> h.length => 3 irb(main):056:0>
.empty?查看是否为空
删除键值
h.delete(key)
irb(main):063:0> h => {"b"=>"B", "cc"=>"CC", "a"=>"aa"} irb(main):064:0> h.delete("a") => "aa" irb(main):065:0> h => {"b"=>"B", "cc"=>"CC"} irb(main):066:0>
delete_if{|key, value| ...}
reject!{|key,value| ...}
irb(main):066:0> h => {"b"=>"B", "cc"=>"CC"} irb(main):067:0> h.delete_if{|k,v| k == "b"} => {"cc"=>"CC"} irb(main):068:0> h => {"cc"=>"CC"} irb(main):069:0> h.reject!{|k,v| k == "cc"} => {} irb(main):070:0> h => {} irb(main):071:0>
reject!,delete_if如果都有符合的条件,那返回的都是排除条件后剩余的字典,如果没有符合的条件,delete_if返回剩余的字典,reject!返回nil
irb(main):072:0> h = {a:"a", b:"b", c:"c"} => {:a=>"a", :b=>"b", :c=>"c"} irb(main):073:0> h.delete_if{|k,v| k == :a} => {:b=>"b", :c=>"c"} irb(main):074:0> h.reject!{|k,v| k == :b} => {:c=>"c"} irb(main):075:0> h => {:c=>"c"} irb(main):076:0> h.reject!{|k,v| k == :d} => nil irb(main):077:0> h.delete_if{|k,v| k == :d} => {:c=>"c"} irb(main):078:0>
初始化散列
.clear
合并两个散列
用了merge的方法
irb(main):084:0> b = {'1':2} => {:"1"=>2} irb(main):085:0> a => {[12, 3]=>12} irb(main):086:0> b => {:"1"=>2} irb(main):087:0> a.merge(b) => {[12, 3]=>12, :"1"=>2} irb(main):088:0> a => {[12, 3]=>12} irb(main):089:0> b => {:"1"=>2} irb(main):090:0> c= a.merge(b) => {[12, 3]=>12, :"1"=>2} irb(main):091:0> c => {[12, 3]=>12, :"1"=>2} irb(main):092:0>
这个是产生一个新值,自身不发生变化
写一个计算单词数量的脚本
#! /usr/bin/env ruby count = Hash.new(0) # 字典默认值是0 File.open(ARGV[0]) do |file| file.each_line do |line| words = line.split words.each do |word| count[word] += 1 end end end # 输出结果进行排序 count.sort do |a, b| a[1] <=> b[1] end.each do |key ,value| print "#{key}: #{value} " end
整个脚本最后意思的就是排序那个部分的sort写法,另外的逻辑也比较清除简单
联系题
1输出表达式如下
wday = {sunday: "星期天", monday: "星期一", tuesday: "星期二", wendesday: "星期三", thursday: "星期四", friday: "星期五", saturday: "星期六"} p wday.keys.size wday.each {|k, v| puts(k.to_s+"是"+v+"。") } ~
定义一个方法
def str2hash(str) hash = {} str.each_line do |line| array = line.chomp.split (array.size/2).times do |i| hash[array[i]] = array[i+1] end end hash end p str2hash("bule 蓝色 white 白色 red 红色") # {"bule"=>"蓝色", "蓝色"=>"white", "red"=>"红色"} ~