美文网首页
Ruby 集合家族之数组(Array)

Ruby 集合家族之数组(Array)

作者: ibob2012 | 来源:发表于2019-08-19 15:17 被阅读0次

    创建数组

    和其他动态语言创建相似。

    >> a = [1, 2, 3]

    => [1, 2, 3]

    >> a.class

    => Array

    >> a.length

    => 3

    >> a.size

    => 3

    >> a[2]

    => 3

    >> a << 4

    => [1, 2, 3, 4]

    >> a

    => [1, 2, 3, 4]

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    其中类型不必相同,可以同时是 String 、Number 等

    ?> a = [1, "Grac Kanil", [2, 3]]

    => [1, "Grac Kanil", [2, 3]]

    >>

    ?> a << true

    => [1, "Grac Kanil", [2, 3], true]

    >> a << 3.14

    => [1, "Grac Kanil", [2, 3], true, 3.14]

    1

    2

    3

    4

    5

    6

    7

    一切皆对象,当然数组跑不了这个范畴

    ?> a = Array.new([1, "Hello", 2])

    => [1, "Hello", 2]

    1

    2

    数组创建可以传参数,提前申请控件,但是数组是动态的,如果传入数组,会创建包含 nil 的数组。nil 也是一个对象,所以再追加,会在 nil 之后添加。当然可以快速传入默认值,占位数组。

    ?> a = Array.new(3)

    => [nil, nil, nil]

    >>

    ?> a = Array.new(3, 1)

    => [1, 1, 1]

    >>

    ?>

    ?> a = Array.new(3)

    => [nil, nil, nil]

    >>

    ?> a << 3

    => [nil, nil, nil, 3]

    ?> a.size

    => 4

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    切割字符串为数组

    scan 方法

    >> s = "This is a test string."

    => "This is a test string."

    >> s.scan(/\w/).join(",")

    => "T,h,i,s,i,s,a,t,e,s,t,s,t,r,i,n,g"

    ?> s.scan(/\b\w*\b/)

    => ["This", "", "is", "", "a", "", "test", "", "string", ""]

    1

    2

    3

    4

    5

    6

    split 方法

    >> s = "This is a test string."

    => "This is a test string."

    ?> s.split(" ")

    => ["This", "is", "a", "test", "string."]

    >> s.split(" ").inspect

    => "[\"This\", \"is\", \"a\", \"test\", \"string.\"]"

    ?> s.split(/\s+/)

    => ["This", "is", "a", "test", "string."]

    >> s.split(/\s+/).inspect

    => "[\"This\", \"is\", \"a\", \"test\", \"string.\"]"

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    % 来实现的语法捷径

    ?> est = "est"

    => "est"

    >> %W{This is a t#{est} string.}

    => ["This", "is", "a", "test", "string."]

    >>

    ?> %w{This is a t#{est} string.}

    => ["This", "is", "a", "t\#{est}", "string."]

    1

    2

    3

    4

    5

    6

    7

    数组越界问题

    很多语言访问不存在的索引,会抛出数组越界异常,但 ruby 中不会,会返回 nil 哦

    ?> a = []

    => []

    >> a[4]

    => nil

    1

    2

    3

    4

    cool!��

    以上是读,如果写入呢?

    ?> a

    => []

    >> a[3] = "Grac"

    => "Grac"

    >> a

    => [nil, nil, nil, "Grac"]

    >> a[7] = "Kanil"

    => "Kanil"

    >>

    ?> a

    => [nil, nil, nil, "Grac", nil, nil, nil, "Kanil"]

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    so cool!

    在很多语言中,如果你的索引值小于 0 呢,又会怎样?

    ?> a = [1, 2, 3]

    => [1, 2, 3]

    >>

    ?> a[-1]

    => 3

    >>

    ?> a[-4]

    => nil

    1

    2

    3

    4

    5

    6

    7

    8

    wonderful!

    数组分类

    表示数组前两个元素的多种表示方法

    ?> strings = %w{a b c d e f g}

    => ["a", "b", "c", "d", "e", "f", "g"]

    >>

    ?> strings[0..1]

    => ["a", "b"]

    >> strings[0...1]

    => ["a"]

    >> strings[0...2]

    => ["a", "b"]

    >> strings[0,2]

    => ["a", "b"]

    >> strings[-7,2]

    => ["a", "b"]

    >> strings[-7..-6]

    => ["a", "b"]

    >> strings[-7...2]

    => ["a", "b"]

    >> strings[-7..1]

    => ["a", "b"]

    >> strings[0..-6]

    => ["a", "b"]

    >> strings[0...-5]

    => ["a", "b"]

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    进阶思考

    >> (0..1).class

    => Range

    ?> strings.[](0..1)

    => ["a", "b"]

    >> strings.[](Range.new(0,1))

    => ["a", "b"]

    1

    2

    3

    4

    5

    6

    有趣的 numerouno

    ➜  ~ gem install numerouno

    Fetching: numerouno-0.2.0.gem (100%)

    Successfully installed numerouno-0.2.0

    Parsing documentation for numerouno-0.2.0

    Installing ri documentation for numerouno-0.2.0

    Done installing documentation for numerouno after 0 seconds

    1 gem installed

    ➜  ~ irb --simple-prompt

    ?> require 'numerouno'

    => true

    >>

    ?> "sixty one".as_number

    => 61

    # 为数组添加英文索引

    ?> class EnglishArray < Array

    >>  def [](idx)

    >>    if String === idx

    >>      self.at(idx.as_number)

    >>    end

    >>  end

    >> end

    => :[]

    >>

    ?> array = EnglishArray.new([1, 2, 3, 4])

    => [1, 2, 3, 4]

    >>

    ?> array["one"]

    => 2

    >> array["three"]

    => 4

    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

    Ruby 数组的万能结构

    可以将数组作为栈。其功能和 Python list 相似,使用 pop 和 push 方法。

    ?> a = []

    => []

    >> a.push(3)

    => [3]

    >> a.push("Grac")

    => [3, "Grac"]

    >>

    ?> a.push("Kanil")

    => [3, "Grac", "Kanil"]

    >>

    ?>

    ?> a.pop

    => "Kanil"

    >> a.pop

    => "Grac"

    >> a.pop

    => 3

    >> a

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    队列

    队列,即先进先出

    ?> a = []

    => []

    >> a.push(1)

    => [1]

    >> a.push(2)

    => [1, 2]

    >> a.push(3)

    => [1, 2, 3]

    >> a.shift

    => 1

    >> a.shift

    => 2

    >> a.shift

    => 3

    >> a

    => []

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    还可以使用 unshift 队首加入新元素

    ?> a = []

    => []

    >> a.push(1)

    => [1]

    >> a.unshift(2)

    => [2, 1]

    >> a.unshift(3)

    => [3, 2, 1]

    1

    2

    3

    4

    5

    6

    7

    8

    使用 delete 删除任意位置元素

    ?> a = [1, 2, 3]

    => [1, 2, 3]

    >> a.delete(2)

    => 2

    >> a

    => [1, 3]

    1

    2

    3

    4

    5

    6

    集合

    ?> [1, 2, 3] + [4, 5, 6]

    => [1, 2, 3, 4, 5, 6]

    ?> [1, 2, 3] + [2, 3]

    => [1, 2, 3, 2, 3]

    >> [1, 2, 3].concat([4, 5, 6])

    => [1, 2, 3, 4, 5, 6]

    >> ["a", 1, 2, 3, "b"] - ["a", "b"]

    => [1, 2, 3]

    >> [1, 2, 4] & [1, 2, 3]

    => [1, 2]

    >> [1, 2, 4] | [1, 2, 3]

    => [1, 2, 4, 3]

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    Ruby 数组常用方法

    检查数组是否为空

    >> a = []

    => []

    >> a.empty?

    => true

    1

    2

    3

    4

    移动元素

    # 转置

    ?> [1, 2, 4].reverse

    => [4, 2, 1]

    # 向左移动一

    ?> [1, 2, 4].rotate

    => [2, 4, 1]

    # 向右移动一

    ?> [1, 2, 4].rotate(-1)

    => [4, 1, 2]

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    安全提示

    ?> a = [1, 2, 3]

    => [1, 2, 3]

    >> a.freeze

    => [1, 2, 3]

    >> a << 4

    RuntimeError: can't modify frozen Array

        from (irb):85

        from /Users/gekang/.rvm/rubies/ruby-2.2.4/bin/irb:11:in `<main>'

    1

    2

    3

    4

    5

    6

    7

    8

    数组的 join 方法,将元素都链接为字符串

    ?> a = [1, 2, "Grac", "Kanil"]

    => [1, 2, "Grac", "Kanil"]

    >>

    ?> a.join

    => "12GracKanil"

    1

    2

    3

    4

    5

    当然,可以传入参数

    ?> a.join(",")

    => "1,2,Grac,Kanil"

    1

    2

    删除嵌套

    ?> [1, [2, 3], [4, ["a", nil]]].flatten

    => [1, 2, 3, 4, "a", nil]

    >>

    ?> [1, [2, 3], [4, ["a", nil]]].flatten(1)

    => [1, 2, 3, 4, ["a", nil]]

    1

    2

    3

    4

    5

    删除副本

    ?> [4, 1, 2, 3, 1, 4].uniq

    => [4, 1, 2, 3]

    1

    2

    检查是否包含某元素

    ?> a = [1, "a", 2]

    => [1, "a", 2]

    >> a.include? "a"

    => true

    >> a.include? 1

    => true

    >> a.include?(1)

    => true

    1

    2

    3

    4

    5

    6

    7

    8

    分割数组

    ?> a = [1, 2, 3, 4, 5, 6]

    => [1, 2, 3, 4, 5, 6]

    >> a.first

    => 1

    >> a.last

    => 6

    >> a.first(3)

    => [1, 2, 3]

    >> a.last(4)

    => [3, 4, 5, 6]

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    统计数组中某元素的个数

    ?> a = [4, 1, 2, 3, 1, 4]

    => [4, 1, 2, 3, 1, 4]

    >> a.count 4

    => 2

    1

    2

    3

    4

    查询数组所有方法

    ?> Array.methods

    => [:[], :try_convert, :allocate, :new, :superclass, :freeze, :===, :==, :<=>, :<, :<=, :>, :>=, :to_s,

    :inspect, :included_modules, :include?, :name, :ancestors, :instance_methods, :public_instance_methods, :protected_instance_methods, :private_instance_methods, :constants, :const_get, :const_set,

    :const_defined?, :const_missing, :class_variables, :remove_class_variable, :class_variable_get,

    :class_variable_set, :class_variable_defined?, :public_constant, :private_constant, :singleton_class?,

    :include, :prepend, :module_exec, :class_exec, :module_eval, :class_eval, :method_defined?,

    :public_method_defined?, :private_method_defined?, :protected_method_defined?, :public_class_method, :private_class_method, :autoload, :autoload?, :instance_method, :public_instance_method, :nil?, :=~,

    :!~, :eql?, :hash, :class, :singleton_class, :clone, :dup, :itself, :taint, :tainted?, :untaint,

    :untrust, :untrusted?, :trust, :frozen?, :methods, :singleton_methods, :protected_methods,

    :private_methods, :public_methods, :instance_variables, :instance_variable_get, :instance_variable_set, :instance_variable_defined?, :remove_instance_variable, :instance_of?, :kind_of?, :is_a?, :tap,

    :send, :public_send, :respond_to?, :extend, :display, :method, :public_method, :singleton_method, :define_singleton_method, :object_id, :to_enum, :enum_for, :equal?, :!, :!=, :instance_eval,

    :instance_exec, :__send__, :__id__]

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    迭代

    迭代可以说是 Ruby 的一大亮点,我觉得 Objective-C 中的迭代就很少使用,比较笨重,更多的会想到写一个 for 循环,然而,Ruby 并不会,优雅的迭代使用起来比较顺手。

    each

    Ruby 中迭代的核心应该就是 each 方法了

    ?> a = ["This", "is", "a", "test", "string"]

    => ["This", "is", "a", "test", "string"]

    >>

    ?> a.each {|s| puts s.cap} # Tab 键可以联想

    s.capitalize  s.capitalize!  s.captures

    ?> a.each { |s| puts s.capitalize }

    This

    Is

    A

    Test

    String

    => ["This", "is", "a", "test", "string"]

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    还有 reverse_each 反向迭代

    ?> a = ["This", "is", "a", "test", "string"]

    => ["This", "is", "a", "test", "string"]

    >> a.reverse_each { |s| puts s.up }

    s.upcase  s.upcase!  s.update  s.upto

    >> a.reverse_each { |s| puts s.upcase }

    STRING

    TEST

    A

    IS

    THIS

    => ["This", "is", "a", "test", "string"]

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    如果你需要索引,当然也给你准备好了当前处理的索引 each_with_index

    >> a = ["This", "is", "a", "test", "string"]

    => ["This", "is", "a", "test", "string"]

    >> a.each_with_index { |s, index| puts "#{index} is #{s}" }

    0 is This

    1 is is

    2 is a

    3 is test

    4 is string

    => ["This", "is", "a", "test", "string"]

    1

    2

    3

    4

    5

    6

    7

    8

    9

    如果你需要迭代数组中某一部分,可以使用分割数组

    ?> a = ["This", "is", "a", "test", "string"]

    => ["This", "is", "a", "test", "string"]

    >> a[0..2]

    => ["This", "is", "a"]

    >> a[0..2].each {|s| puts s}

    This

    is

    a

    => ["This", "is", "a"]

    1

    2

    3

    4

    5

    6

    7

    8

    9

    也可以使用 Range 来实现

    ?> a = ["This", "is", "a", "test", "string"]

    => ["This", "is", "a", "test", "string"]

    >>

    ?> (0..2).each {|i| puts a[i]}

    This

    is

    a

    => 0..2

    1

    2

    3

    4

    5

    6

    7

    8

    map 或 collect

    >> a = [1, 2, 3]

    => [1, 2, 3]

    >> a.map { |i| i + 1 }

    => [2, 3, 4]

    1

    2

    3

    4

    如果只是让每一个元素调用方法,不关心每个元素的值时,可以使用快捷写法

    >> a = [1, 2, 3]

    => [1, 2, 3]

    >> a.map(&:to_f)

    => [1.0, 2.0, 3.0]

    1

    2

    3

    4

    #map 不改变原来的数组,而是会生成新的数组,如果需要修改原数组,需要使用 #map! 方法

    >> a = [1, 2, 3]

    => [1, 2, 3]

    >> a.map(&:to_f)

    => [1.0, 2.0, 3.0]

    >>

    ?> a

    => [1, 2, 3]

    >> a.map!(&:to_f)

    => [1.0, 2.0, 3.0]

    >> a

    => [1.0, 2.0, 3.0]

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    #map 和 #collect 相同,可以互换使用

    ?> a = [1, 2, 3]

    => [1, 2, 3]

    >> a.map(&:to_f)

    => [1.0, 2.0, 3.0]

    >> a.collect(&:to_f)

    => [1.0, 2.0, 3.0]

    ————————————————

    版权声明:本文为CSDN博主「GracKanil」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。

    原文链接:https://blog.csdn.net/grackanil/article/details/81869817

    相关文章

      网友评论

          本文标题:Ruby 集合家族之数组(Array)

          本文链接:https://www.haomeiwen.com/subject/klassctx.html