数组类 Array
数组的创建方法
Array.new 可以接收0,1,2是那种参数
>> Array.new => [] >> Array.new(5) => [nil, nil, nil, nil, nil] >> Array.new(5,3) => [3, 3, 3, 3, 3] >>
使用%w或%i来创建
>> %w(hello world) => ["hello", "world"] >> %i(hello world) => [:hello, :world] >>
使用to_a创建
>> (2..10).to_a => [2, 3, 4, 5, 6, 7, 8, 9, 10] >> hash = {"abc"=>1, "cde"=>2} => {"abc"=>1, "cde"=>2} >> hash.to_a => [["abc", 1], ["cde", 2]] >>
使用字符串的spilt方法
=> "hello world" >> str.split() => ["hello", "world"] >>
索引的使用方法
a[n] 取n索引的元素
a[n..m]或a[n...m]取n到m的元素,或者n到m-1的元素
a[n,len]从n索引开始的,len个元素
a.at(n) 等价 a[n]
a.slice(n) 等价 a[n]
a.slice(n..m)等价a[n..m]
a.slice(n, m) 等价a[n, m]
替换元素
同样支持切片赋值
irb(main):002:0> arr = (1..5).to_a => [1, 2, 3, 4, 5] irb(main):003:0> arr[1..2] => [2, 3] irb(main):004:0> arr[1..2] = [7,8,9,] => [7, 8, 9] irb(main):005:0> arr => [1, 7, 8, 9, 4, 5] irb(main):006:0>
插入元素
插入元素比较有意思,书中用的[x,y]形式
irb(main):006:0> arr = ('a'.."f").to_a => ["a", "b", "c", "d", "e", "f"] irb(main):007:0> arr[2,0] = ["x", "y"] => ["x", "y"] irb(main):008:0> arr => ["a", "b", "x", "y", "c", "d", "e", "f"] irb(main):009:0> arr[5..5] = ["5", "6"] => ["5", "6"] irb(main):010:0> arr => ["a", "b", "x", "y", "c", "5", "6", "e", "f"] irb(main):011:0>
irb(main):011:0> arr[7...7] = ["7", "7"]
=> ["7", "7"]
irb(main):012:0> arr
=> ["a", "b", "x", "y", "c", "5", "6", "7", "7", "e", "f"]
通过arr[n,0]或者arr[n...n]对n的位置进行插入元素,元素用arr的形式
起始就像切片赋值的方式进行了插入
取出指定的值获取的元素组成新的arr
irb(main):013:0> arr => ["a", "b", "x", "y", "c", "5", "6", "7", "7", "e", "f"] irb(main):014:0> arr.values_at(1,2,3,7,99) => ["b", "x", "y", "7", nil] irb(main):015:0>
ruby没有集合的概念,数组就可以直接拿来当集合用
交集 & 并集 |
是只有一个符号
差集 -
还可以合并用 +
模拟栈或者队列形式操作数组
对数组的开头进行操作 追加元素 unshift 删除元素 shift 引用元素 first
结尾进行操作 追加元素push 删除元素 pop 引用元素 last
=> ["b", "x", "y", "c", "5", "6", "7", "7", "e", "f"] irb(main):019:0> arr.size => 10 irb(main):020:0> arr.first => "b" irb(main):021:0> arr.first => "b" irb(main):022:0> arr.size => 10 irb(main):023:0> arr.methods => [:to_h, :include?, :at, :fetch, :last, :union, :difference, :push, :append, :pop, :shift, :unshift, :each_index, :join, :rotate, :rotate!, :sort!, :sort_by!, :collect!, :map!, :select!, :filter!, :keep_if, :values_at, :delete_at, :delete_if, :reject!, :transpose, :fill, :assoc, :rassoc, :uniq!, :compact, :compact!, :flatten, :flatten!, :shuffle!, :shuffle, :*, :+, :permutation, :&, :repeated_permutation, :combination, :sample, :repeated_combination, :product, :bsearch, :-, :sort, :bsearch_index, :count, :find_index, :select, :filter, :reject, :collect, :map, :first, :all?, :any?, :one?, :none?, :reverse_each, :zip, :take, :take_while, :drop, :drop_while, :cycle, :sum, :uniq, :|, :insert, :<=>, :<<, :index, :rindex, :replace, :==, :clear, :pack, :[], :[]=, :empty?, :eql?, :max, :min, :reverse, :inspect, :concat, :prepend, :reverse!, :length, :size, :each, :to_ary, :delete, :to_a, :to_s, :slice, :slice!, :dig, :hash, :to_set, :find, :entries, :sort_by, :grep, :grep_v, :detect, :find_all, :flat_map, :collect_concat, :inject, :reduce, :partition, :group_by, :minmax, :min_by, :max_by, :minmax_by, :member?, :each_with_index, :each_entry, :each_slice, :each_cons, :each_with_object, :chunk, :slice_before, :slice_after, :slice_when, :chunk_while, :chain, :lazy, :instance_variable_defined?, :remove_instance_variable, :instance_of?, :kind_of?, :is_a?, :tap, :instance_variable_get, :instance_variable_set, :instance_variables, :singleton_method, :method, :public_send, :define_singleton_method, :public_method, :extend, :to_enum, :enum_for, :===, :=~, :!~, :respond_to?, :freeze, :object_id, :send, :display, :nil?, :class, :singleton_class, :clone, :dup, :itself, :yield_self, :then, :taint, :tainted?, :untaint, :untrust, :untrusted?, :trust, :frozen?, :methods, :singleton_methods, :protected_methods, :private_methods, :public_methods, :equal?, :!, :__id__, :instance_exec, :!=, :instance_eval, :__send__] irb(main):024:0> arr => ["b", "x", "y", "c", "5", "6", "7", "7", "e", "f"] irb(main):025:0> arr.push("push") => ["b", "x", "y", "c", "5", "6", "7", "7", "e", "f", "push"] irb(main):026:0> arr.unshift("unshift") => ["unshift", "b", "x", "y", "c", "5", "6", "7", "7", "e", "f", "push"] irb(main):027:0> arr.pop => "push" irb(main):028:0> arr.last => "f" irb(main):029:0>
跟Python比就一个pop是通用的
数组的主要方法
unshift 插入头部数据
<< 跟 push 一样
a.concat(b) 等于 +号 相同与Python的extend
切片赋值前面已经都讲过了
由于Ruby跟Python一样属于引用传参,所以当两个变量名指向同一个arr,任何一个操作,都会影响另外一个
可以通过freeze冻结,通过dup赋值一个解冻的
irb(main):034:0> arr.freeze => ["a", "b", "c"] irb(main):035:0> arr[0]= 9 Traceback (most recent call last): 4: from /usr/bin/irb:23:in `<main>' 3: from /usr/bin/irb:23:in `load' 2: from /Library/Ruby/Gems/2.6.0/gems/irb-1.0.0/exe/irb:11:in `<top (required)>' 1: from (irb):35 FrozenError (can't modify frozen Array) irb(main):036:0> b = arr.dup => ["a", "b", "c"] irb(main):037:0> b.pop => "c" irb(main):038:0> b => ["a", "b"] irb(main):040:0> arr => ["a", "b", "c"] irb(main):041:0>
Python中集合也可以用freeze,这样可以当做一种深拷贝使用不错
从数组中删除元素
irb(main):046:0> b => ["a", nil, "b", nil] irb(main):047:0> b.compact => ["a", "b"] irb(main):048:0> b => ["a", nil, "b", nil] irb(main):049:0> b.compact! => ["a", "b"] irb(main):050:0> b => ["a", "b"] irb(main):051:0>
compact删除重复元素,如果带!会对自身进行修改
delete方法,删除执行名称的元素,只要名字相同可以删除多个
irb(main):052:0> b << "b" => ["a", "b", "b"] irb(main):053:0> b.delete "b" => "b" irb(main):054:0> b => ["a"] irb(main):055:0>
delete_at方法,删除指定位置的元素
irb(main):058:0> b => ["a", 1, 2, 3, 4, 5] irb(main):059:0> b.delete_at(-1) => 5 irb(main):060:0> b => ["a", 1, 2, 3, 4] irb(main):061:0>
delete_if 删除后面指定条件
reject 排除该条件以外的
reject! 改变自身
irb(main):066:0> b => [1, 2, 3, 4] irb(main):067:0> b.reject{|n| n>1} => [1] irb(main):068:0> b.delete_if{|n| n<3} => [3, 4] irb(main):069:0> b => [3, 4] irb(main):070:0>
删除指定元素
slice!
irb(main):072:0> arr = %w(a b c d e f g) => ["a", "b", "c", "d", "e", "f", "g"] irb(main):073:0> arr.slice!(0) => "a" irb(main):074:0> arr => ["b", "c", "d", "e", "f", "g"] irb(main):075:0> arr.slice!(1..2) => ["c", "d"] irb(main):076:0> arr => ["b", "e", "f", "g"] irb(main):077:0> arr.slice!(1,9) => ["e", "f", "g"] irb(main):078:0> arr => ["b"] irb(main):079:0>
uniq 去重的
uniq! 自身去重
不掩饰了
shift 取首个元素
pop 取最后一个元素
替换数组元素
collect 与map collect返回的还是一个arr,现在测试用起来
irb(main):085:0> arr => [1, 2, 3, 4, 5] irb(main):087:0> arr.collect!{|n| n**n} => [1, 4, 27, 256, 3125] irb(main):088:0> arr => [1, 4, 27, 256, 3125] irb(main):089:0> arr.map{|n| n+1} => [2, 5, 28, 257, 3126] irb(main):090:0> arr.map!{|n| n+1} => [2, 5, 28, 257, 3126] irb(main):091:0> arr => [2, 5, 28, 257, 3126] irb(main):092:0> arr.map!{|n| Math.sqrt(n)} => [1.4142135623730951, 2.23606797749979, 5.291502622129181, 16.0312195418814, 55.910642993977454] irb(main):093:0> arr => [1.4142135623730951, 2.23606797749979, 5.291502622129181, 16.0312195418814, 55.910642993977454] irb(main):094:0>
经过测试,没发现map跟collect的差别
fill 填充
一个参数,全部填充这个
fill(value)
fill(value, begin)
fill(value, begin, end)
fill(value, n..m)
irb(main):096:0> arr.fill(999) => [999, 999, 999, 999, 999] irb(main):097:0> arr => [999, 999, 999, 999, 999] irb(main):098:0> arr.fill(0,2) => [999, 999, 0, 0, 0] irb(main):099:0> arr.fill(6,1,2) => [999, 6, 6, 0, 0] irb(main):100:0> arr.fill(6,3..5) => [999, 6, 6, 6, 6, 6] irb(main):101:0>
flatten
flatten!修改自身,取出嵌套的效果,变成一个没有嵌套的数组
irb(main):101:0> a = [1,[2,[3]],4,[[5]]] => [1, [2, [3]], 4, [[5]]] irb(main):102:0> a.flatten! => [1, 2, 3, 4, 5] irb(main):103:0> a => [1, 2, 3, 4, 5] irb(main):104:0>
reverse反转
reverse!自身反转
sort排序,默认都是从小到大
sort_by 必须通过{}填写参数
前面章节,已经介绍过具体用法
数组与迭代器
collect返回个一个array对象
irb(main):104:0> a = 1..5 => 1..5 irb(main):105:0> b = a.collect{|n| n**n} => [1, 4, 27, 256, 3125] irb(main):106:0> b => [1, 4, 27, 256, 3125] irb(main):107:0> a => 1..5 irb(main):108:0> a.map{|n| n**n} => [1, 4, 27, 256, 3125] irb(main):109:0>
处理数组中的元素
for 循环处理
list = [1, 3, 7, 9] sum = 0 for i in 0...list.size sum += list[i] end print "合计为#{sum}"
另外用each或each_with_index 或者对arr进行pop方法,调用 while
while item = a.pop
## 对item进行处理
end
创建矩阵
a = Array.new(3, [0,0,0])
这个创建的举证,每个元素指向同一个地址
需要不同的地址,要这么写
shijianongdeMBP:chapter_13 shijianzhong$ cat t.rb a = Array.new(3) do [0, 0, 0] end p a
还有一种.new后面通过{}的形式创建array
irb(main):001:0> Array.new(5){|i| i + 1} => [1, 2, 3, 4, 5] irb(main):002:0> Array.new(5){|i| i ** i} => [1, 1, 4, 27, 256] irb(main):003:0> Array.new(5){|i| i} => [0, 1, 2, 3, 4] irb(main):004:0>
同时访问多个数组
就写一个zip的用法
shijianongdeMBP:chapter_13 shijianzhong$ cat sum_with_zip.rb ary1 = [1, 2, 3, 5] ary2 = [10, 20, 30, 40, 50] ary3 = 100.step(500, 100) result = [] ary1.zip(ary2, ary3) do |a, b, c| result.push( a + b + c) end p result
irb(main):001:0> [].methods => [:to_h, :include?, :at, :fetch, :last, :union, :difference, :push, :append, :pop, :shift, :unshift, :each_index, :join, :rotate, :rotate!, :sort!, :sort_by!, :collect!, :map!, :select!, :filter!, :keep_if, :values_at, :delete_at, :delete_if, :reject!, :transpose, :fill, :assoc, :rassoc, :uniq!, :compact, :compact!, :flatten, :flatten!, :shuffle!, :shuffle, :*, :+, :permutation, :&, :repeated_permutation, :combination, :sample, :repeated_combination, :product, :bsearch, :-, :sort, :bsearch_index, :count, :find_index, :select, :filter, :reject, :collect, :map, :first, :all?, :any?, :one?, :none?, :reverse_each, :zip, :take, :take_while, :drop, :drop_while, :cycle, :sum, :uniq, :|, :insert, :<=>, :<<, :index, :rindex, :replace, :==, :clear, :pack, :[], :[]=, :empty?, :eql?, :max, :min, :reverse, :inspect, :concat, :prepend, :reverse!, :length, :size, :each, :to_ary, :delete, :to_a, :to_s, :slice, :slice!, :dig, :hash, :to_set, :find, :entries, :sort_by, :grep, :grep_v, :detect, :find_all, :flat_map, :collect_concat, :inject, :reduce, :partition, :group_by, :minmax, :min_by, :max_by, :minmax_by, :member?, :each_with_index, :each_entry, :each_slice, :each_cons, :each_with_object, :chunk, :slice_before, :slice_after, :slice_when, :chunk_while, :chain, :lazy, :instance_variable_defined?, :remove_instance_variable, :instance_of?, :kind_of?, :is_a?, :tap, :instance_variable_get, :instance_variable_set, :instance_variables, :singleton_method, :method, :public_send, :define_singleton_method, :public_method, :extend, :to_enum, :enum_for, :===, :=~, :!~, :respond_to?, :freeze, :object_id, :send, :display, :nil?, :class, :singleton_class, :clone, :dup, :itself, :yield_self, :then, :taint, :tainted?, :untaint, :untrust, :untrusted?, :trust, :frozen?, :methods, :singleton_methods, :protected_methods, :private_methods, :public_methods, :equal?, :!, :__id__, :instance_exec, :!=, :instance_eval, :__send__] irb(main):002:0>
内置的方法实在太多了
练习题
1.创建一个数组a,使1到100的整数按升序排列
irb(main):002:0> Array.new(100){|i| i} => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99] irb(main):003:0> (0...100).to_a => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99] irb(main):004:0>
2.不创建新的数组,使1的数组的每个元素扩大100倍
irb(main):006:0> arr.map!{|num| num*100} => [0, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000, 2100, 2200, 2300, 2400, 2500, 2600, 2700, 2800, 2900, 3000, 3100, 3200, 3300, 3400, 3500, 3600, 3700, 3800, 3900, 4000, 4100, 4200, 4300, 4400, 4500, 4600, 4700, 4800, 4900, 5000, 5100, 5200, 5300, 5400, 5500, 5600, 5700, 5800, 5900, 6000, 6100, 6200, 6300, 6400, 6500, 6600, 6700, 6800, 6900, 7000, 7100, 7200, 7300, 7400, 7500, 7600, 7700, 7800, 7900, 8000, 8100, 8200, 8300, 8400, 8500, 8600, 8700, 8800, 8900, 9000, 9100, 9200, 9300, 9400, 9500, 9600, 9700, 9800, 9900] irb(main):007:0> arr => [0, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000, 2100, 2200, 2300, 2400, 2500, 2600, 2700, 2800, 2900, 3000, 3100, 3200, 3300, 3400, 3500, 3600, 3700, 3800, 3900, 4000, 4100, 4200, 4300, 4400, 4500, 4600, 4700, 4800, 4900, 5000, 5100, 5200, 5300, 5400, 5500, 5600, 5700, 5800, 5900, 6000, 6100, 6200, 6300, 6400, 6500, 6600, 6700, 6800, 6900, 7000, 7100, 7200, 7300, 7400, 7500, 7600, 7700, 7800, 7900, 8000, 8100, 8200, 8300, 8400, 8500, 8600, 8700, 8800, 8900, 9000, 9100, 9200, 9300, 9400, 9500, 9600, 9700, 9800, 9900] irb(main):008:0>
3 获取1数组中是3的倍数的元素,创建新数组a3。不创建新数组,把3的倍数以外的元素全部删除
irb(main):017:0> a3 = arr.select{|num| num % 3 == 0} => [3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99] irb(main):018:0> a3 => [3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99] irb(main):019:0> arr.delete_if{|num| num % 3 == 0} => [1, 2, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26, 28, 29, 31, 32, 34, 35, 37, 38, 40, 41, 43, 44, 46, 47, 49, 50, 52, 53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80, 82, 83, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 100] irb(main):020:0> arr => [1, 2, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26, 28, 29, 31, 32, 34, 35, 37, 38, 40, 41, 43, 44, 46, 47, 49, 50, 52, 53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80, 82, 83, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 100] irb(main):021:0>
4将1数组的元素按倒序排序
irb(main):024:0> arr.sort_by{|i| -i} => [100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1] irb(main):025:0>
5 求1数组中的和
irb(main):026:0> sum = 0 => 0 irb(main):027:0> arr.each{|i| sum +=i} => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100] irb(main):028:0> p sum 5050 => 5050 irb(main):029:0>
6 直接上代码
irb(main):030:0> result = Array.new => [] irb(main):031:0> 10.times do |i| irb(main):032:1* result << arr[i*10,10] irb(main):033:1> end => 10 irb(main):034:0> p result [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [11, 12, 13, 14, 15, 16, 17, 18, 19, 20], [21, 22, 23, 24, 25, 26, 27, 28, 29, 30], [31, 32, 33, 34, 35, 36, 37, 38, 39, 40], [41, 42, 43, 44, 45, 46, 47, 48, 49, 50], [51, 52, 53, 54, 55, 56, 57, 58, 59, 60], [61, 62, 63, 64, 65, 66, 67, 68, 69, 70], [71, 72, 73, 74, 75, 76, 77, 78, 79, 80], [81, 82, 83, 84, 85, 86, 87, 88, 89, 90], [91, 92, 93, 94, 95, 96, 97, 98, 99, 100]] => [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [11, 12, 13, 14, 15, 16, 17, 18, 19, 20], [21, 22, 23, 24, 25, 26, 27, 28, 29, 30], [31, 32, 33, 34, 35, 36, 37, 38, 39, 40], [41, 42, 43, 44, 45, 46, 47, 48, 49, 50], [51, 52, 53, 54, 55, 56, 57, 58, 59, 60], [61, 62, 63, 64, 65, 66, 67, 68, 69, 70], [71, 72, 73, 74, 75, 76, 77, 78, 79, 80], [81, 82, 83, 84, 85, 86, 87, 88, 89, 90], [91, 92, 93, 94, 95, 96, 97, 98, 99, 100]] irb(main):035:0>
7定义方法sum_array,计算数值数组nums1和num2中相对应的各个元素的合计值,并将结果作为数组返回。
#! /usr/bin/env ruby def sum_array(arr1, arr2) new_arr = [] arr1.zip(arr2).each do |x,y| new_arr.push(x+y) end new_arr end p sum_array([1, 2, 3], [4, 6, 8])