["a","b",3,"abcdef"]#数组可以嵌套使用d=["a","c",[1,2,3]]#=>["a","c",[1,2,3]]数组的索引:数组的各个元素按顺序被赋予了从0开始的编号" />

Ruby中数组的常用方法

Ruby中数组的常用方法
Ruby中数组的常用方法

Ruby中数组的常用方法

数组是许多指向对象的引用按顺序排列的数据结构。数组中保存的是“指向对象的引用”,而不是对象本身。

数组的创建:

#数组不一定都是同一类型

c = ["a", "b", 3, "abcdef"] #=> ["a", "b", 3, "abcdef"]

#数组可以嵌套使用

d = ["a", "c", [1, 2, 3]] #=> ["a", "c", [1, 2, 3]]

数组的索引:

数组的各个元素按顺序被赋予了从0开始的编号,可以使用这些编号和索引运算符[]对访问对象进行操作。如果访问的索引值指向的元素不存在,则返回nil

负索引:

负索引的存在,在Ruby中非常具有代表性。Ruby中的数组对象的索引值是负数,是从末尾开始反向编号所表示的元素。

数组的最后一个元素的编号是-1,在它前面的一个元素编号则是-2,以此类推。

带有长度的索引:

c = ["a", "b", 3, "abcdef"]

利用负索引进行访问倒数两个索引值指向的元素

puts c[-2,2] #=> [3, "abcdef"]

对范围外进行访问

puts c[4,2] #=> nil

表示范围的索引:

c = [1, "str", 3, "abcdef"]

..表示包含末端的范围

...表示不包含末端的范围

#包含末端的范围

puts c[0..1] #=> [1, "str"]

#不包含末端的范围

puts c[0...1] #=> [1]

c = [1, "str", 3, "abcdef"]

#负索引组合,-2表示倒数编号,3表示正数编号

puts c[0..-1] #=> [1, "str", 3, "abcdef"]

puts c[-2..3] #=> [3, "abcdef"]

puts c[-2...3] #=> [3]

puts c[4..5] #=> nil

索引赋值:

使用索引值可以对数组的内容进行替换。

a = [1, 2]

a[0] = 3

puts a #=> [3, 2]

#能够对超过数组长度的位置进行赋值,此时数组会被自动延长,空白索引部分用nil填充a = [1, 2]

a[4] = "4"

puts a #=> [1, 2, nil, nil, "4"]

a[0, 3] = 'a', 'b', 'c'

puts a #=> ["a", "b", "c", nil, "4"]

#当指定的元素个数比原数组的元素个数多时,数组会被加长并代入

a = [1, 2]

a[0, 3] = 'a', 'b', 'c', 'd'

puts a #=> ["a", "b", "c", "d"]

a[1..2] = 1, 2

puts a #=> ["a", 1, 2, "d"]

a[0..2] = 'A' #<------请注意-----

puts a #=> ["A", "d"]

数组的各种各样的方法:

array = ["a", "b", "c"]

#输出数组的长度

puts array.length #=> 3

#输出数组的元素个数(即长度)

puts array.size #=> 3 puts array.count #=>3

array = ["a", "b", "c"]

#array的元素copy

puts array *=2 #=> ["a", "b", "c", "a", "b", "c"]

#是否包含c

puts array.include?("c") #=> true

#对数组进行排序,生成新的数组,并不改变原来的array数组

puts array.sort #=> ["a", "a", "b", "b", "c", "c"]

puts array #=> ["a", "b", "c", "a", "b", "c"]

#消除重复元素,并不改变原来的array数组

puts array.uniq #=> ["a", "b", "c"]

puts array #=> ["a", "b", "c", "a", "b", "c"]

#消除重复元素,并更新原来的array数组

puts array.uniq! #=> ["a", "b", "c"]

puts array #=> ["a", "b", "c"]

带有代码块的方法和迭代:

对带有代码块的方法的调用进行编程时可以用do ... end 与花括号{}。

do ... end 和花括号{}的区别仅仅在于结合强度而已。

do ... end一般用于不在同行的代码块中。

{}一般用于代码比较少,可以写在一行的代码块中。

数组对象拥有很多带有代码块的方法,其中很多是对反复操作的抽象化,成为迭代方法。其中最具代表性的是each。

array = ["a", "b", "c"]

array.each do |item|

print item + ""

end

#=> "abc"

带有序数的反复操作:

each_with_index是each的一种变体,能够同时获取数组元素和其索引值

array = ["a", "b", "c"]

array.each_with_index { |item, index| p [item, index] }

#输出结果 ["a", 0] ["b", 1] ["c", 2]

映射(Map):

acids = ["Adenin", "Thymine", "Guanine", "Cytosine"]

sign = acids.map{|acid| acid[0, 1]} #或用acid.first取出字符串中第一个字符p sign #=> ["A", "T", "G", "C"]

acids = ["Adenin", "Thymine", "Guanine", "Cytosine"]

#对acids内的元素分别进行小写转为大写,a为临时变量

sign = acids.map{|a| a.upcase} #可以简写: acids.map(&:upcase)

p sign #=> ["ADENIN", "THYMINE", "GUANINE", "CYTOSINE"]

排序:

array = ["73", "2", "5", "1999", "53"]

#按照默认的字符串排序

p array.sort #=> ["1999", "2", "5", "53", "73"]

#转化为数值后排序

p array.sort{|x,y| x.to_i <=> y.to_i}

#=>["2", "5", "53", "73", "1999"]

选择:

将代码块中的返回值为真的元素取出,组成新的数组并返回

#select是find_all的别名

例:students.select{ |person| person.grade == 3 }

创建新数组

使用array#map 或者array#collect方法

#collect是map的别名

a = [10, 20, 30, 40, 50]

p a.collect {|x| x*10} #=> [100, 200, 300, 400, 500]

p a.map {|x| x*10} #=> [100, 200, 300, 400, 500]

#初始化

a = [] #定义一个空数组a

a = Array.new #定义一个数组a

puts a #=>[]

a = Array.new(5) #定义一个含5个nil元素的数组

puts a #=>[nil, nil, nil, nil, nil]

a = Array.new(5,0) #定义一个含5个0元素的数组

puts a #=>[0, 0, 0, 0, 0]

city = ["北京", "上海", "广州"]

puts city #=> ["北京", "上海", "广州"]

city = Array.new

city[0] = "北京"

city[1] = "上海"

city[2] = "广州"

p city #=> ["北京", "上海", "广州"]

city = %w(北京上海广州)

p city #=> ["北京", "上海", "广州"]

#使用split函数进行分隔

city = '北京,上海,广州'.split(',')

p city #=> ["北京", "上海", "广州"]

#使用%W{...}将字符串转换成数组双引号,可转义

str = "深圳"

city_1 = %W{北京上海广州 #{str}}

p city_1 #=>["北京", "上海", "广州", "深圳"]

#使用%w{...}进行转换,单引号,不转义

str = "深圳"

city_2 = %w{北京上海广州 #{str}}

p city_2 #=>["北京", "上海", "广州", "\#{str}"]

r = 1..5 # Range

#使用to_a、entries将范围类型数据转换成数组

p r.to_a # Array, to_a等同于entries #=> [1, 2, 3, 4, 5] p r.entries

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

r = 'a'..'e'

p r.to_a

#=> ["a", "b", "c", "d", "e"]

基本操作

#数组的长度会按需要自动增加

city = Array.new

puts "数组的长度为:" + city.size.to_s #=> 0

city[2] = "香港"

puts "数组的长度为:" + city.size.to_s #=> 3

p city #=> [nil, nil, "香港"]

city = ["北京", "上海", "广州", "深圳"]

#对一个元素赋值

city[4] = "香港"

#得到数组长度

puts "数组的长度为:" + city.size.to_s #=> 数组的长度为:5

puts "数组的长度为:" + city.length.to_s #=> 5

puts "数组的长度为:" + city.count.to_s #=> 5

p city #=> ["北京", "上海", "广州", "深圳", "香港"]

#获取某一元素

puts "第二个元素为:" + city[1] #上海

puts "倒数第二个元素为:" + city[-2] #深圳

college = ["北京大学", "清华大学"]

#数组添加一个元素,可以使用Array#<<的方法,Array#unshift方法,Array#push。

#array#<<将元素追加到最后;array#unshift方法可以将元素添加到数组开头;Array#push方法可以被添加到的数组元素的结尾.

#从开头或结尾的数组元素删除

#Array#shift的方法,从数组头部删除。

#array#pop方法,从数组的尾部删除。

college.unshift("浙江大学", "复旦大学") #向数组头部添加元素列表

college.shift #从数组头部删除元素

college.push("南京大学", "武汉大学") #向数组尾部添加元素列表

college << "南开大学" #向数组尾部添加一个元素

college.pop #从数组尾部删除元素

puts college.size.to_s #=> 7

p college #=> ["浙江大学", "复旦大学", "北京大学", "清华大学", "南京大学", "武汉大学", "南开大学"] #获取数组第一个元素,first(n),取前n个元素

p college.first #=> "浙江大学"

p college.first(3) #=> ["浙江大学", "复旦大学", "北京大学"]

#获取数组最后一个元素,last(n),取后n个元素

p https://www.360docs.net/doc/ba15821441.html,st #=> "南开大学"

p https://www.360docs.net/doc/ba15821441.html,st(3) #=> ["南京大学", "武汉大学", "南开大学"]

puts college.shift #删除并获取数组第一个元素

puts college.pop #删除并获取数组最后一个元素,

#注意:pop和push组合起来可以把一个Array直接当成Stack

puts college.size.to_s #=> 5

p college #=> ["复旦大学", "北京大学", "清华大学", "南京大学", "武汉大学"]

p college[2,3] #截取从索引2开始,长度为3的元素列表

p college[2..3] #截取从索引2开始,到索引3的元素列表

p college[2...3] #截取从索引2开始,到索引3(不包括)的元素列表

city_1 = ["北京", "上海", "广州"]

city_2 = ["香港", "澳门"]

city_3 = city_1 + city_2

puts city_3.size.to_s #=> 5

city_1.concat(city_2)

puts city_1.size.to_s #=> 5

#两数组相连+ 或 concat

#a.concat(b),连结,得到a中所有数据和b中所有数据组成的数组,并保存在a中,a变b不变p ["北京", "上海", "广州"].concat(["广州", "香港", "澳门"])

#=> ["北京", "上海", "广州", "广州", "香港", "澳门"]

#a + b,和集,得到a中所有数据和b中所有数据组成的数组,a、b均不变

p ["北京", "上海", "广州"] + ["广州", "香港", "澳门"]

#=> ["北京", "上海", "广州", "广州", "香港", "澳门"]

#a - b,差集,得到由a中元素去除同时存在于a数组和b数组中的元素后剩余元素组成的数组p ["北京", "上海", "广州"] - ["北京", "香港", "澳门"]

#=> ["上海", "广州"]

#a & b,交集,取两个数组中都存在的元素,等于 a - (a - b)和b - (b - a)

p (["北京", "上海", "广州"] & ["北京", "香港", "澳门"]) #=> ["北京"]

#a | b,并集,合并两个数组,并保证元素的唯一性,等于(a - b) + (b - a) + (a & b) p (["北京", "上海", "上海", "广州"] | ["北京", "香港", "澳门"])

#=> ["北京", "上海", "广州", "香港", "澳门"]

Array#include?(obj),判断数组元素中是否包含指定对象

citys = ["北京", "上海", "广州", "香港", "澳门"]

puts citys.include? ("上海") #=> true

Array#delete(X),删除数组中所有与X相同的元素,返回X

citys = ["北京", "上海", "广州", "北京", "香港", "澳门"]

p citys.delete("北京") #=> "北京"

p citys #=> ["上海", "广州", "香港", "澳门"]

Array#delete_at(n),删除第n个元素,返回被删除的元素对象

citys = ["北京", "上海", "广州", "北京", "香港", "澳门"]

p citys.delete_at(3) #=> "北京"

p citys #=> ["北京", "上海", "广州", "香港", "澳门"]

Array#delete_if,删除满足条件的元素,返回处理后的原数组

abc = [ "a", "b", "b", "b", "c" ]

p abc.delete_if {|x| x >= "b" } #=> ["a"]

Array#slice/each_slice/each_cons

#slice(m, n)返回原数组中下标为m到下标为n之间的元素组成的数组

#slice!(m, n),同时改变原数组,从原数组中删除返回的元素

citys = ["北京", "上海", "广州", "香港", "澳门"]

p citys.slice(1, 3) #=> ["上海", "广州", "香港"]

p citys #=> ["北京", "上海", "广州", "香港", "澳门"]

p citys.slice!(1, 3) #=> ["上海", "广州", "香港"]

p citys #=> ["北京", "澳门"]

#each_slice,迭代取出间隔分割的数组,返回nil

citys = ["北京", "上海", "广州", "香港", "澳门"]

citys.each_slice(2){ |city| p city }

#=> ["北京", "上海"] ["广州", "香港"] ["澳门"]

#each_cons,迭代取出滑动分组的数组,返回nil

citys = ["北京", "上海", "广州", "香港", "澳门"]

citys.each_cons(2){ |city| p city }

#=> ["北京", "上海"] ["上海", "广州"] ["广州", "香港"] ["香港", "澳门"]

#insert(n, obj),在某序列前插入元素对象,改变原数组。

citys = ["北京", "上海", "广州", "香港", "澳门"]

p citys.insert(2, "2") #=> ["北京", "上海", "2", "广州", "香港", "澳门"]

p citys #=> ["北京", "上海", "2", "广州", "香港", "澳门"]

#a[n..m],选择改变数组

citys = ["北京", "上海", "广州", "香港", "澳门"]

citys[1..3] = [1, 2, 3]

p citys #=> ["北京", 1, 2, 3, "澳门"]

Array#flatten,将数组中类型为数组的元素中的所有元素取出,插入原数组中,重复这个操作,直到原数组中所有的元素的数据类型均不为数组

Array#flatten(n),重复n次转变操作,结束后数组中元素仍可能为数组

nums = [[1, 2], [[2, 3], [3, 4]], 6]

p nums.flatten #=> [1, 2, 2, 3, 3, 4, 6]

s = [ 1, 2, 3 ] #= [1, 2, 3]

t = [ 4, 5, 6, [7, 8] ] # [4, 5, 6, [7, 8]]

a = [ s, t, 9, 10 ] # [[1, 2, 3], [4, 5, 6, [7, 8]], 9, 10]

p a.flatten #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

a = [ 1, 2, [3, [4, 5] ] ]

p a.flatten(1) #=> [1, 2, 3, [4, 5]]

p a.flatten #=> [1, 2, 3, 4, 5]

Array#uniq,去重,保证元素唯一

nums = [1, 1, 2, 2, 3, 3]

p a.uniq #=>[1, 2, 3]

#排序--升序

arr = [9, 8, 7, 1, 2, 5, 3]

p arr.sort #=> [1, 2, 3, 5, 7, 8, 9]

p arr #=> [9, 8, 7, 1, 2, 5, 3]

p arr.sort! #=> [1, 2, 3, 5, 7, 8, 9]

p arr #=> [1, 2, 3, 5, 7, 8, 9]

#排序--降序(注意<=>两边的a,b的位置)

p arr.sort{ |a, b| b<=>a } #=> [9, 8, 7, 5, 3, 2, 1]

arr.sort{ |a,b| a.to_s <=> b.to_s }

说明:在这arr是一个数组对象,a和b代表相邻的两个元素。本方法使用了to_s方法把nil转换为一个空字符串,这样就可以对含有nil的数组进行排序了。此外,这个数组本身的值不会发生任何变化。

wuwei = ['酸', '甘', '苦', '辛', '咸']

Array#min/min_by/max/max_by取最小/大值,均不改变原数组

Array #minmax/minmax_by,返回最小值、最大值组成的数组,均不改变原数组

#取最小值

puts wuwei.min #=> 咸

#取最大值

puts wuwei.max #=> 酸

puts wuwei.min_by do |v| #=> 咸

v = '0'

end

puts wuwei.max_by do |w| #=> 酸

w = '1'

end

p wuwei #=> ["酸", "甘", "苦", "辛", "咸"]

p wuwei.minmax #=> ["咸", "酸"]

p wuwei.minmax_by do |w| #=> ["咸", "酸"]

w

end

整数型数组求和:

inject是reduce的别名

[1,2,3,4,5,6].inject(0){ |sum,value| sum += value } #rails2支持

# 或 [1,2,3,4,5,6].inject(:+) #rails3以上支持

#=> 21

%w(a b c).each_with_index.inject([]) do |result, (value,index)|

result << value + index.to_s

end

#=> ["a0", "b1", "c2"]

#从数组中随机选取指定的个数(此方法在rails3.2.13后面版本已移除):

arr = [1,3,5,6,7,8,9]

arr.sample(3) #=> [3,1,9]

arr.sample #=> 4

#等价于

arr[rand(arr.size-1)] # 3

#shuffle,打乱元素顺序,随机变化(洗牌)

nums = [ 1, 2, 3 ]

p nums.shuffle #=> [2, 3, 1]

p nums.shuffle #=> [3, 2, 1]

p nums.shuffle #=> [1, 3, 2]

p nums.shuffle #=> [1, 3, 2]

nums[rand(num.size)] #rand随机数,在0~(num.size-1)之间随机一个数

#遍历

#each/each_with_index/cycle/cycle(n)

Array#each依次取出每一个元素,每次取出的一个元素可以被跟随的块函数接收,返回原数组;Array #each_with_index得到元素的同时还得到当前元素在数组中的序列值,返回原数组

Array #cycle,除非遇到break、return、exit等语句,否则无限循环数组,返回nil

Array #cycle(n),除非遇到break、return、exit等语句,否则循环数组n次,返回nil nums = [1, 2, 3]

b = nums.each{ |value| p value } #=>1 2 3

puts b #=> [1, 2, 3]

nums.each_with_index do |value, index|

puts "#{index} : #{value}"

puts ( value + index ).to_s

end

abc = ("a".."c").to_a

abc.cycle {|x| puts x } #=> a, b, c, a, b, c,.. forever. abc.cycle(2) {|x| puts x } #=> a, b, c, a, b, c.

reduce,别名inject,迭代累加/减,不改变原数组

arry = (1..3).to_a #=> [1, 2, 3]

n = arry.reduce(:+)

puts n #=> 6

n = arry.reduce(:-)

puts n #=> -4

#inject理解的难点在于block中的两个参数

#sum是上一次block的返回值,默认初始化为0或nil

#带有初始值的累加

c = 10

#可以传入初始值c

n = arry.reduce(c) do |sum, value| #value是当前的元素对象

p sum

sum + value

end

puts n

#=>10

#=>11

#=>13

#=>16

puts n = arry.inject(:+) #=> 6

abc = ('a'..'c').to_a

puts abc.inject(:+) #=> "abc"

puts abc.inject("A") { |sum, value| sum + value } #=> "Aabc" #join 返回由数组中各元素连结成的一个字符串,原数组不变

abc = ['a', 'b', 'c']

p abc.join #=> "abc"

p abc.join('-') #=> "a-b-c"

p abc #=> ["a", "b", "c"]

# map <--> collect

#map, 别名collect,处理数组中的每一个元素并放入新数组中,返回新数组#map!、collect!将同时改变原数组

arry = %w(a b cD)

p arry #=> ["a", "b", "cD"]

s1 = arry.reduce(:+) #=> "abcD"

s2 = arry.map(&:upcase) #=> "ABCD"

s3 = arry.map do |item|

item.upcase

end

s3 = arry.map{ |item| item.upcase }

p arry #=>["a", "b", "cD"]

p s1 #=>"abcD"

p s2 #=>["A", "B", "CD"]

p s3 #=>["A", "B", "CD"]

#find <-> detect / find_all <-> select

# find找到一个即返回,别名detect

# detect是find别名

rs = (1..8).to_a.find {|i|

i % 2 == 0 and i % 4 == 0

}

p rs #=> 4

# find_all找到全部符合条件的对象,别名select

rs = (1..8).to_a.select {|i|

i % 2 == 0 and i % 4 == 0

}

p rs #=> [4, 8]

# select,找到全部符合条件的对象,别名find_all

arry = (1..8).to_a

arrySelect = arry.select { |x|

x % 2 == 0

}

puts arrySelect.to_s #=> [2, 4, 6, 8]

#take(n)/take_while/drop(n)/drop_while

#取前n个元素/取满足条件的元素/取除去前n个元素剩余的元素/取除去满足条件的元素剩余的元素

#返回这些元素组成的数组,不改变原数组

a = ["北京", "上海", "广州", "香港", "澳门"]

p b = a.take(2) #=> ["北京", "上海"]

p a #=> ["北京", "上海", "广州", "香港", "澳门"]

p b = a.drop(2) #=> ["广州", "香港", "澳门"]

b = a.take_while{|value|

value == "北京"

}

p b #=> ["北京"]

b = a.drop_while{|value|

value == "北京"

}

p b #=> ["上海", "广州", "香港", "澳门"]

# reject,迭代数组元素,从原数组中删除符合条件的元素对象,改变原数组,返回处理后的数组arry = (1..8).to_a

arryReject = arry.reject { |x| x % 2 == 0 }

puts arryReject.to_s #=> [1, 3, 5, 7]

# select是find_all的别名

arry = *(1..8)

arrySelect = arry.select { |x| x % 2 == 0 }

puts arrySelect #=> [2, 4, 6, 8]

Array#group_by根据条件分组,分组后得到哈希表

arry = (1..8).to_a

arryGroupBy = arry.group_by{ |x| x % 2 == 0 }

puts arryGroupBy #=> {false=>[1, 3, 5, 7], true=>[2, 4, 6, 8]}

puts arryGroupBy.class #=> Hash

value = arryGroupBy[false]

p value #=> [1, 3, 5, 7]

puts value.class #=> Array

arryGroupBy = arry.group_by{ |x| 2 }

puts arryGroupBy #=> {2=>[1, 2, 3, 4, 5, 6, 7, 8]}

value = arryGroupBy[2]

p value #=> [1, 2, 3, 4, 5, 6, 7, 8]

puts value.class #=>Array

Array#zip(Array,...),遍历数组,对每个元素,从各个数组参数中取出与其序列相同的元素,组成新的数组作为代码块的传入参数,返回nil

a = [1, 4, 7]

b = [2, 5, 8]

c = [3, 6, 9]

d = a.zip(b, c){|e|

p e

e

}

p d

#=> [1, 2, 3]

#=> [4, 5, 6]

#=> [7, 8, 9]

#=> nil

Array#to_enum,转变成枚举类型,这样可以使用next,不改变原数组,返回生成的枚举对象

a=[1, 4, 7]; f = a.to_enum

p f.next #=> 1

p f.next #=> 4

#all? 迭代取出元素并代入代码块,代码块均返回真?

#any? 迭代取出元素并代入代码块,代码块至少有一次返回真?#none? 迭代取出元素并代入代码块,代码块均不返回真?

#one? 迭代取出元素并代入代码块,代码块有且仅有一次返回真?#返回真或假,原数组内容不变

wuxing = ['金', '木', '水', '火', '土']

puts wuxing.all?{|value| #=> false

value == '木'

}

puts wuxing.any?{|value| #=> true

value == '木'

}

puts wuxing.none?{|value| #=> false

value == '木'

}

puts wuxing.one?{|value| #=> true

value =='木'

}

p wuxing #=> ["金", "木", "水", "火", "土"]

数组的运算:

<<:追加元素

a = []

#推荐使用

if a.respond_to?(:<<) [then]

a << 1

end

# 不推荐使用

# if a.kind_of?(Array) then a << 1 end

# if a.instance_of?(Array) then a << 1 end

#=> [1]

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

+:串联方法(不去重)

[1,2] + [1,2] #=> [1,2,1,2]

-:数组差集

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

&:数组交集

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

| :数组并集(去重)

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

*:重复数组

若是整数,则返回重复整数次的数组,若是字符串,则返回重复使用该字符串连接数组。[1,2] * 2 #[1,2,1,2,1,2]

[1,2] * '--' #1--2

数组具有所有Enumerable模块所提供的方法:

a = [1,2,3,4,5]

a.select{ |i| i%2 == 0 }

#=> [2,4]

a.max #=> 5

a.min #=> 1

a.include?(5) #=> true

a.inject{ |sum,i| sum + i } #=> 15

a.delete_if{ |item| block } #删除指定条件的元素

a.first和https://www.360docs.net/doc/ba15821441.html,st #返回数组的第一个元素/最后一个元素

https://www.360docs.net/doc/ba15821441.html,pact #返回一个数组的副本,并删除其中的nil元素

a.clear #清空数组

a.flattern #如果ary中包含的元素为数组,将不断递归合并,返回一个只包含基本元素的数组[1,[2,3],[4,[5,6]],7].flattern

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

a.pop和a.shift #删除数组中最后一个元素/第一个元素

a.push(obj) #类似于<<方法,将obj添加到数组的尾部

a.unshift(obj) #将obj添加到数组的首部

提取一个子数组

你可以把部分的数组用array#slice的方法或Array#[]的方法来提取出来。

a = [1,2,3,4,5]

puts a[0,2] #=> [1, 2]

puts a[1..3] #=> [2, 3, 4]

puts a.slice(0,2) #=> [1, 2]

puts a.slice(1..3) #=> [2, 3, 4]

清空数组

您可以用array#clear方法清空数组所有元素。

a = [1,2,3,4,5]

a.clear #=> []

ruby 数组操作

数组的创建

arr = Array.new(num) #创建num个元素的数组,所有数组元素为nil

arr = Array.new(num, elem) #创建num个元素的数组,所有数组元素为elem

arr = Array(m..n) #创建m..n元素为m到n的数组(包括n) m...n不包括n

arr = [elem1, elem2, ....elemn]

arr = Array.[](elem1, elem2, ...........elemn)

arr = %w(string1, string2,....stringn)

数组的修改

插入 : arr.insert(pos, elem)

删除 : arr.delete(elem) / arr.delete(pos)

修改 : arr[pos]= new_elem /arr[start..end]= / arr[start...end]= /arr[start, length]= 栈 : arr.push / arr.pop

队列 : arr.shift / arr.unshift

新增 : arr1 + arr2 #只能是两个数组加、 arr1.concat(arr2)、arr1 << elem 或 arr2

集合运算

arr1 & arr2 arr1 | arr2 arr1 - arr2

压缩

https://www.360docs.net/doc/ba15821441.html,pact #去除所有nil,注意不能递归,多维数组之中的nil是不能用这个去掉

arr.uniq(!) #压缩所有重复元素

转换

arr.to_s / arr.join(delimiter) /arr.sort(!) / arr.reverse(!)

arr.flatten #将多维数组编程一维

arr.transpose #将记录转换为列

清空

arr.clear

检索数组

arr.index(elem) #返回elem的位置

arr[pos] #返回pos位置的元素

arr.at(pos) #同上

判断

arr.include?(elem)

arr.empty?

复制数组:

当使用”=”将一个数组变量赋值给另一个数组变量时,这两个数组变量引用的仍然是同一个数组,修改其中一个数组的值,另一个也会修改。我们可以使用clone方法复制一个新数组:

arr = ["one","two","three"]

arr1= arr #arr和arr1引用的还是同一个数组,修改一个另一个也会修改

arr2=arr.clone #arr2是arr的一个新版本,修改arr2不影响arr

数组排序:

Sort方法使用比较操作符 <=> 来比较一个数组中邻近的元素的大小,但是这个不能比较一个数组中包含有nil的值的情况;

arr.sort{|a,b| a.to_s <=> b.to_s}

说明:在这arr是一个数组对象,a和b代表相邻的两个元素。本方法使用了to_s方法把nil转换为一个空字符串,这样就可以对含有nil的数组进行排序了。此外,这个数组本身的值不会发生任何变在。

添加和删除数组元素:

向数组添加元素:

unshift:向数组头部添加数组元素

push: 向数组头部尾数组元素

<< : 向数组尾部添加一个数组元素

向数组删除元素:shift:从头部删除元素返回被删除元素 / pop:从尾删除元素返回被删除元素

根据条件从数组中选择(数组中查询)

#detect是find别名

x = [5,8,12,9,4,30]

x.detect { |e| e % 6 == 0 } #=>12 可以被6整除(取余为0的)

x.find { |e| e % 2 == 0 } #=>8 可以被2整除(取余为0的) 只返回第一个数组

#select是find_all的别名

x.find_all {|e| e % 2 == 0} #=>[8,12,4,30]可以被2整除(取余为0的) 返回所有满足条件的x.select { |e| e % 2 == 0 } #=>[8,12,4,30]可以被2整除(取余为0的) 返回所有满足条件的#reject,取相反的

x.reject{ |e| e % 2 == 0 } #=>[5,9]可以被2整除(取余为0的) 返回所有满足相反条件的

正则查询

a = %w[January February March April May] #=> ["January", "February", "March", "April", "May"] a.grep(/ary/) #=> ["January", "February"]

a.grep(/ary/){ |i| i.length } #=> [7, 8] 查询出来的内容转换为个数.

b = [1,20,5,7,13,33,15,28] #=> [1, 20, 5, 7, 13, 33, 15, 28]

#查询12到24之间的数平方

b.grep(12..24){ |n| n * n } #=> [400, 169, 225]

追加和连续的区别:

+ :给一个数组添加元素,创建一个新的数组,不去重

a = [1, 2, 3, 4];

b = [4, 5, 6]

p(a + b) #=> [1, 2, 3, 4, 4, 5, 6] 元素不去重

p(a | b) #=> [1, 2, 3, 4, 5, 6] 元素去重

<< :给一个数据添加元素,直接操作原数组,当给一个数组添加的新元素也是一个数组时,该新元素作为数组的最后一个元素: p(a << b) #=> [1, 2, 3, 4, [4, 5, 6]] 元素追加

#并行赋值

arr = ["item1", "item2", "item3", "item4"]; a,b,c,d = *arr;

a = [1,2,3,4];

b = [5,6,7,8]

a.zip(b) #=> [[1,5],[2,6],[3,7],[4,8]]

a.zip(b).map{|x,y| x + y}

#=> [6,8,10,12]

C语言几种常见的排序方法

C语言几种常见的排序方法 2009-04-2219:55 插入排序是这样实现的: 首先新建一个空列表,用于保存已排序的有序数列(我们称之为"有序列表")。 从原数列中取出一个数,将其插入"有序列表"中,使其仍旧保持有序状态。 重复2号步骤,直至原数列为空。 插入排序的平均时间复杂度为平方级的,效率不高,但是容易实现。它借助了"逐步扩大成果"的思想,使有序列表的长度逐渐增加,直至其长度等于原列表的长度。 冒泡排序 冒泡排序是这样实现的: 首先将所有待排序的数字放入工作列表中。 从列表的第一个数字到倒数第二个数字,逐个检查:若某一位上的数字大于他的下一位,则将它与它的下一位交换。 重复2号步骤,直至再也不能交换。 冒泡排序的平均时间复杂度与插入排序相同,也是平方级的,但也是非常容易实现的算法。 选择排序 选择排序是这样实现的: 设数组内存放了n个待排数字,数组下标从1开始,到n结束。 i=1 从数组的第i个元素开始到第n个元素,寻找最小的元素。 将上一步找到的最小元素和第i位元素交换。 如果i=n-1算法结束,否则回到第3步 选择排序的平均时间复杂度也是O(n²)的。 快速排序 现在开始,我们要接触高效排序算法了。实践证明,快速排序是所有排序算法中最高效的一种。它采用了分治的思想:先保证列表的前半部分都小于后半部分,然后分别对前半部分和后半部分排序,这样整个列表就有序了。这是一种先进的思想,也是它高效的原因。因为在排序算法中,算法的高效与否与列表中数字间的比较次数有直接的关系,而"保证列表的前半部分都小于后半部分"就使得前半部分的任何一个数从此以后都不再跟后半部分的数进行比较了,大大减少了数字间不必要的比较。但查找数据得另当别论了。 堆排序 堆排序与前面的算法都不同,它是这样的: 首先新建一个空列表,作用与插入排序中的"有序列表"相同。 找到数列中最大的数字,将其加在"有序列表"的末尾,并将其从原数列中删除。 重复2号步骤,直至原数列为空。 堆排序的平均时间复杂度为nlogn,效率高(因为有堆这种数据结构以及它奇妙的特征,使得"找到数列中最大的数字"这样的操作只需要O(1)的时间复杂度,维护需要logn的时间复杂度),但是实现相对复杂(可以说是这里7种算法中比较难实现的)。

数组对象的常用方法

数组对象的常用方法: 什么叫方法:方法其实就是函数!——只是如果一个函数“隶属于”某个“对象”,则称这个函数为该对象的方法。 function maibao(){ document.write(“啦啦啦,我是卖报的小行家,卖报啦卖报啦。”); } var myDreamGirl = { name: “小花”, age:18, edu :”大学”, sex:”女”, nengli1: function (){ document.write(“洗衣!”); } , nengli2: function (){ document.write(“做饭!”); } , nengli3: maibao }; var v1 = [2, 5, 1, 5]; var v2 = [5, 1, 6, 8]; 从严格的角度来说,数组也是一种对象——甚至字符串也是对象。 v1作为对象,就有属性和方法: 属性: 某数组.length: 表示该数组对象的长度 方法: 某数组.concat(其他数组):将两个数组连接起来成为一个新的“更长”的数组。 var s1 = v1.concat( v2 ); //此时s1是这样一个数组: [2, 5, 1, 5, 5, 1, 6, 8];

某数组.join(“字符串”):将数组中的所有项以指定的字符“串接起来”成为“长的”一个字符串。 var s2 = v1.join(“//”); //结果s2为字符串“2//5//1//5” 某数组.pop(); //将该数组的最后一项“移除”(删除),并返回该项数据,即该数组少了一项 var s3 = v1.pop(); //结果v1只剩这个:[2,5,1]; s3的值是5 某数组.push(新数据项d1); //将新的数据d1添加到该数组的最后位置,即数组多了一项。 var s4 = v1.push( 55 ); //v1此时为:[2,5,1, 55], s4的值为新数组的长度,即4 某数组.shift(); //将该数组的第一项“移除”(删除),并返回该项数据,即该数组少了一项 var s5 = v1.shift(); //结果v1只剩这个:[5, 1,55]; s5的值是2 某数组.unshift(新数据项d1); //将新的数据d1添加到该数组的最前位置,即数组多了一项。 var v6 = v1.unshift( 66 ); //v1此时为:[66, 5, 1, 55],s6的值为新数组的长度,即4 javascript语言是一门基于对象的语言。 字符串对象: var str1 = new String(“abcdefgabc”); //这是一个“字符串对象” var str2 = “abcdefgabc”; //这个字符串跟前面str1几乎没有区别

实验2基本数据类型与数组(最新整理)

民族学院实验报告 计算机科学 系 级 班 指导教师 报告人20 年 月 日 成 绩 课程名称 JAVA 语言程序设计实验名称实验二 基本数据类型与数组实验 目的 1.掌握基本数据类型及其相互之间的转换2.掌握JAVA 中数组的使用实验仪器 和器材具有JDK 环境的计算机一台 实验内容和要求 一、输出希腊字母表 1.请按模板要求,将【代码】替换为Java 程序代码,运行该程序时在命令窗口中输出希腊字母表。其运行效果如图 2.1所示。 图2.1 输出希腊字母表 GreekAlphabet.java public class GreekAlphabet { public static void main(String[] args) { int startPosition=0,endPosition=0; char cStart='α',cEnd='ω'; startPosition=(int )cStart; //cStart 做int 型数据转换,并将结果赋值给startPosition endPosition=(int )cEnd; //cEnd 做int 型数据转换,并将结果赋值给EndPosition System.out.println("希腊字母\'α\'在Unicode 表中的顺序位置:"+(int)cStart); System.out.println("希腊字母表:"); for (int i=startPosition;i<=endPosition;i++){ char c='\0'; cStart=(char )i; //i 做char 型转换运算,并将结果赋值给c System.out.print(" "+c); if ((i-startPosition+1)%10==0) System.out.println(); } } } 2.实验后练习 (1)将一个double 型数据直接赋值给float 型变量,程序编译时提示怎样的 错误? 答:程序提示的内容为:“可能损失精度”。 (2)在应用程序的main 方法中增加语句:

四种简单的排序算法

1.插入排序 算法思想 插入排序使用了两层嵌套循环,逐个处理待排序的记录。每个记录与前面已经排好序的记录序列进行比较,并将其插入到合适的位置。假设数组长度为n,外层循环控制变量i 由1至n-1依次递进,用于选择当前处理哪条记录;里层循环控制变量j,初始值为i,并由i至1递减,与上一记录进行对比,决定将该元素插入到哪一个位置。这里的关键思想是,当处理第i条记录时,前面i-1条记录已经是有序的了。需要注意的是,因为是将当前记录与相邻的上一记录相比较,所以循环控制变量的起始值为1(数组下标),如果为0的话,上一记录为-1,则数组越界。 现在我们考察一下第i条记录的处理情况:假设外层循环递进到第i条记录,设其关键码的值为X,那么此时有可能有两种情况: 1.如果上一记录比X大,那么就交换 它们,直到上一记录的关键码比X 小或者相等为止。 2.如果上一记录比X小或者相等,那 么之前的所有记录一定是有序的, 且都比X小,此时退出里层循环。 外层循环向前递进,处理下一条记 录。 算法实现(C#) public class SortAlgorithm { // 插入排序 public static void InsertSort(T[] array, C comparer) where C:IComparer {

for (int i = 1; i <= array.Length - 1; i++) { //Console.Write("{0}: ", i); int j = i; while (j>=1 && https://www.360docs.net/doc/ba15821441.html,pare(array[j], array[j - 1]) < 0) { swap(ref array[j], ref array[j-1]); j--; } //Console.WriteLine(); //AlgorithmHelper.PrintArray(arr ay); } } // 交换数组array中第i个元素和第j个元素 private static void swap(ref T x,ref T y) { // Console.Write("{0}<-->{1} ", x, y); T temp = x; x = y; y = temp; } } 上面Console.WriteLine()方法和AlgorithmHelper.PrintArray()方法仅仅是出于测试方便,PrintArray()方法依次打印了数组的内容。swap()方法则用于交换数组中的两

jni中基本类型数组的传递方法(无需拷贝数据)

JNI中基本类型数组的传递方法(无需拷贝数据!!!) 0、先来看一下主要用到哪些函数: C 代码GetIntArrayElements();//貌似得到的是副本,要拷贝数据ReleaseIntArrayElements();//对应上面的函数的释放资源的函数env->GetPrimitiveArrayCritical();//貌似 得到的是指向原数据的指针 env->ReleasePrimitiveArrayCritical();////对应上面的函数 的释放资源的函数 官方文档: https://www.360docs.net/doc/ba15821441.html,/javase/7/docs/technotes/guides/jni/ spec/functions.html#wp17440 JNI函数的中译本(貌似没看到GetPrimitiveArrayCritical()):https://www.360docs.net/doc/ba15821441.html,/qinjuning下面正式开始:1、不知道如 何设置JNI环境的先看这里: https://www.360docs.net/doc/ba15821441.html,/blog/13281362、Java端程序: Java端:

Java代码package tests; import java.util.Arrays; public class TestJNIArray { static{ System.loadLibrary("TestJNIArra y"); } public static native void addOne(int[] ints);//数组元素1 public static native void addOne(double[] ints);//数组元素1,为了测试,C 中循环了5次public static native int[] getNewArray(int size,int initValue);//生成初始值为initValue的数组,数组长度为size public static void main(String[] args) throws InterruptedException { int n=20; final int[] a=new int[n]; for (int i = 0; i < a.length; i ) { a[i]=i; } if(n<50)System.out.println(Arrays.toString(a)); addOne(a); if(n<50)System.out.println(Arrays.toString(a)); final double d[]=new double[n]; for (int i = 0; i < d.length; i ) { d[i]=i; } //addOne(d); if(n<50)System.out.println(Arrays.toString(d)); new Thread(new Runnable() { @Override

C语言中数组排序算法及函数调用

C语言中数组排序算法及函数调用 一、冒泡法(起泡法) 算法要求:用起泡法对10个整数按升序排序。 算法分析:如果有n个数,则要进行n-1趟比较。在第1趟比较中要进行n-1次相邻元素的两两比较,在第j趟比较中要进行n-j次两两比较。比较的顺序从前往后,经过一趟比较后,将最值沉底(换到最后一个元素位置),最大值沉底为升序,最小值沉底为降序。 算法源代码: # include main() { int a[10],i,j,t; printf("Please input 10 numbers: "); /*输入源数据*/ for(i=0;i<10;i++) scanf("%d",&a[i]); /*排序*/ for(j=0;j<9;j++) /*外循环控制排序趟数,n个数排n-1趟*/ for(i=0;i<9-j;i++) /*内循环每趟比较的次数,第j趟比较n-j次*/ if(a[i]>a[i+1]) /*相邻元素比较,逆序则交换*/ { t=a[i]; a[i]=a[i+1]; a[i+1]=t; } /*输出排序结果*/ printf("The sorted numbers: "); for(i=0;i<10;i++) printf("%d ",a[i]); printf("\n"); } 算法特点:相邻元素两两比较,每趟将最值沉底即可确定一个数在结果的位置,确定元素位置的顺序是从后往前,其余元素可能作相对位置的调整。可以进行升序或降序排序。 算法分析:定义n-1次循环,每个数字比较n-j次,比较前一个数和后一个数的大小。然后交换顺序。二、选择法 算法要求:用选择法对10个整数按降序排序。 算法分析:每趟选出一个最值和无序序列的第一个数交换,n个数共选n-1趟。第i趟假设i为最值下标,然后将最值和i+1至最后一个数比较,找出最值的下标,若最值下标不为初设值,则将最值元素和下标为i的元素交换。 算法源代码: # include main() { int a[10],i,j,k,t,n=10; printf("Please input 10 numbers:"); for(i=0;i<10;i++)

JAVA类与对象及数组习题及答案

JAV A类和对象及数组习题 一、选择题 (1)下列构造方法的调用方式中,正确的是(D )--原因:在通过new实例化一个类对象时系统会自动调用该类相应的构造方法。 A.按照一般方法调用B.由用户直接调用 C.只能通过new自动调用D.被系统调用 (2)在Java中,能实现多重继承效果的方式是(C )--原因:一个类可以同时实现多个接口。Java接口反映了对象较高层次的抽象,还弥补了Java只支持单继承的不足,可用它来完成多继承的一些功能。 A.内部类B.适配器C.接口D.同步 (3)int型public成员变量MAX_LENGTH,该值保持为常数100,则定义这个变量的语句是( D )—原因:java中定义常量用关键字final来定义。 A.public int MAX_LENGTH=100 B.final int MAX_LENGTH=100 C.public const int MAX_LENGTH=100 D.public final int MAX_LENGTH=100 (4)下列叙述中,正确的是( A )—原因:Java严格区分大小写,所以变量number 与Number不相同;Java 中的注释方式除了“//”行注释之外还有段注释“/*-------*/”和文档注释/**-------*/。Java源文件中的public类只能有一个。 A. 声明变量时必须指定一个类型 B. Java认为变量number与Number相同 C. Java中唯一的注释方式是"//" D. 源文件中public类可以有0或多个 (5)下列叙述中,错误的是( D )—原因:子类继承父类,并且可以有自己的成员变量和成员方法。所以可以认为子类是父类的扩展。

数据结构中几种常见的排序算法之比较

几种常见的排序算法之比较 2010-06-20 14:04 数据结构课程 摘要: 排序的基本概念以及其算法的种类,介绍几种常见的排序算法的算法:冒泡排序、选择排序、插入排序、归并排序、快速排序、希尔排序的算法和分析它们各自的复杂度,然后以表格的形式,清晰直观的表现出它们的复杂度的不同。在研究学习了之前几种排序算法的基础上,讨论发现一种新的排序算法,并通过了进一步的探索,找到了新的排序算法较之前几种算法的优势与不足。 关键词:排序算法复杂度创新算法 一、引言 排序算法,是计算机编程中的一个常见问题。在日常的数据处理中,面对纷繁的数据,我们也许有成百上千种要求,因此只有当数据经过恰当的排序后,才能更符合用户的要求。因此,在过去的数十载里,程序员们为我们留下了几种经典的排序算法,他们都是智慧的结晶。本文将带领读者探索这些有趣的排序算法,其中包括介绍排序算法的某些基本概念以及几种常见算法,分析这些算法的时间复杂度,同时在最后将介绍我们独创的一种排序方法,以供读者参考评判。 二、几种常见算法的介绍及复杂度分析 1.基本概念 1.1稳定排序(stable sort)和非稳定排序 稳定排序是所有相等的数经过某种排序方法后,仍能保持它们在排序之前的相对次序,。反之,就是非稳定的排序。 比如:一组数排序前是a1,a2,a3,a4,a5,其中a2=a4,经过某种排序后为 a1,a2,a4,a3,a5, 则我们说这种排序是稳定的,因为a2排序前在a4的前面,排序后它还是在a4的前面。假如变成a1,a4,a2,a3,a5就不是稳定的了。 1.2内排序( internal sorting )和外排序( external sorting) 在排序过程中,所有需要排序的数都在内存,并在内存中调整它们的存储顺序,称为内排序;在排序过程中,只有部分数被调入内存,并借助内存调整数在外存中的存放顺序排序方法称为外排序。

JS对象创建数组

1 创建对象 Document