forked from rurema/doctree
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Enumerable
1639 lines (1235 loc) · 53.1 KB
/
Enumerable
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
= module Enumerable
繰り返しを行なうクラスのための Mix-in。このモジュールの
メソッドは全て each を用いて定義されているので、インクルード
するクラスには each が定義されていなければなりません。
[[c:Array]], [[c:Hash]], [[c:Range]], [[c:Enumerator]]等のクラスで、
Enumerableモジュールはインクルードされています。ただし、効率化のため、
そのクラスでEnumerableと同名・同等の機能を再定義(オーバーライド)しているケースも少なくなく、
特にArrayクラスでは同名のメソッドを再定義していることが多いです。
== Instance Methods
--- all? -> bool
--- all? {|item| ... } -> bool
#@since 2.5.0
--- all?(pattern) -> bool
#@end
すべての要素が真である場合に true を返します。
偽である要素があれば、ただちに false を返します。
ブロックを伴う場合は、各要素に対してブロックを評価し、すべての結果
が真である場合に true を返します。ブロックが偽を返した時点で、
ただちに false を返します。
#@since 2.5.0
@param pattern ブロックの代わりに各要素に対して pattern === item を評価します。
#@end
#@samplecode 例
require 'set'
# すべて正の数か?
p Set[5, 6, 7].all? {|v| v > 0 } # => true
p Set[5, -1, 7].all? {|v| v > 0 } # => false
p Set[].all? {|v| v > 0 } # => true
#@since 2.5.0
p Set['ant', 'bear', 'cat'].all?(/t/) # => false
#@end
#@end
#@since 2.6.0
@see [[m:Array#all?]]
#@end
--- any? -> bool
--- any? {|item| ... } -> bool
#@since 2.5.0
--- any?(pattern) -> bool
#@end
すべての要素が偽である場合に false を返します。
真である要素があれば、ただちに true を返します。
ブロックを伴う場合は、各要素に対してブロックを評価し、すべての結果
が偽である場合に false を返します。ブロックが真を返した時点
で、ただちに true を返します。
#@since 2.5.0
@param pattern ブロックの代わりに各要素に対して pattern === item を評価します。
#@end
#@samplecode 例
require 'set'
p Set[1, 2, 3].any? {|v| v > 3 } # => false
p Set[1, 2, 3].any? {|v| v > 1 } # => true
p Set[].any? {|v| v > 0 } # => false
#@since 2.5.0
p Set['ant', 'bear', 'cat'].any?(/d/) # => false
p Set[nil, true, 99].any?(Integer) # => true
#@end
p Set[nil, true, 99].any? # => true
p Set[].any? # => false
#@end
@see [[m:Array#any?]]
#@since 2.6.0
--- chain(*enums) -> Enumerator::Chain
自身と enums 引数を続けて繰り返す [[c:Enumerator::Chain]] を返します。
#@samplecode 例
e = (1..3).chain([4, 5])
e.to_a #=> [1, 2, 3, 4, 5]
#@end
@see [[m:Enumerator#+]]
#@end
--- collect -> Enumerator
--- map -> Enumerator
--- collect {|item| ... } -> [object]
--- map {|item| ... } -> [object]
各要素に対してブロックを評価した結果を全て含む配列を返します。
ブロックを省略した場合は [[c:Enumerator]] を返します。
#@samplecode 例
# すべて 3 倍にした配列を返す
p (1..3).map {|n| n * 3 } # => [3, 6, 9]
p (1..3).collect { "cat" } # => ["cat", "cat", "cat"]
#@end
#@since 2.6.0
@see [[m:Hash#to_h]], [[m:Array#collect]], [[m:Array#map]]
#@else
@see [[m:Array#collect]], [[m:Array#map]]
#@end
--- each_with_index(*args) -> Enumerator
--- each_with_index(*args) {|item, index| ... } -> self
要素とそのインデックスをブロックに渡して繰り返します。
ブロックを省略した場合は、
要素とそのインデックスを繰り返すような
[[c:Enumerator]] を返します。
[[m:Enumerator#with_index]] は offset 引数を受け取りますが、
each_with_index は受け取りません (引数はイテレータメソッドにそのまま渡されます)。
@param args イテレータメソッド (each など) にそのまま渡されます。
#@samplecode 例
[5, 10, 15].each_with_index do |n, idx|
p [n, idx]
end
# => [5, 0]
# [10, 1]
# [15, 2]
#@end
#@samplecode 引数ありの例
require 'stringio'
StringIO.new("foo|bar|baz").each_with_index("|") do |s, i|
p [s, i]
end
# => ["foo|", 0]
# ["bar|", 1]
# ["baz", 2]
#@end
@see [[m:Enumerator#with_index]]
--- find(ifnone = nil) -> Enumerator
--- detect(ifnone = nil) -> Enumerator
--- find(ifnone = nil) {|item| ... } -> object
--- detect(ifnone = nil) {|item| ... } -> object
要素に対してブロックを評価した値が真になった最初の要素を返します。
真になる要素が見つからず、ifnone も指定されていないときは nil を返します。
真になる要素が見つからず、ifnone が指定されているときは ifnone を call した結果を返します。
ブロックを省略した場合は [[c:Enumerator]] を返します。
@param ifnone call メソッドを持つオブジェクト (例えば [[c:Proc]]) を指定します。
#@samplecode 例
# 最初の 3 の倍数を探す
p [1, 2, 3, 4, 5].find {|i| i % 3 == 0 } # => 3
p [2, 2, 2, 2, 2].find {|i| i % 3 == 0 } # => nil
# ifnone の使用例
ifnone = proc { raise ArgumentError, "item not found" }
p [1, 2, 3, 4, 5].find(ifnone) {|i| i % 7 == 0 }
# ArgumentError: item not found
#@end
--- find_all -> Enumerator
--- select -> Enumerator
#@since 2.6.0
--- filter -> Enumerator
#@end
--- find_all {|item| ... } -> [object]
--- select {|item| ... } -> [object]
#@since 2.6.0
--- filter {|item| ... } -> [object]
#@end
各要素に対してブロックを評価した値が真であった要素を全て含む配列を
返します。真になる要素がひとつもなかった場合は空の配列を返します。
ブロックを省略した場合は [[c:Enumerator]] を返します。
#@samplecode 例
(1..10).find_all # => #<Enumerator: 1..10:find_all>
(1..10).find_all { |i| i % 3 == 0 } # => [3, 6, 9]
[1,2,3,4,5].select # => #<Enumerator: [1, 2, 3, 4, 5]:select>
[1,2,3,4,5].select { |num| num.even? } # => [2, 4]
#@end
@see [[m:Enumerable#reject]]
@see [[m:Enumerable#grep]]
#@since 2.7.0
--- filter_map {|item| ... } -> [object]
--- filter_map -> Enumerator
各要素に対してブロックを評価した値のうち、真であった値の
配列を返します。
ブロックを省略した場合は [[c:Enumerator]] を返します。
#@samplecode 例
(1..10).filter_map { |i| i * 2 if i.even? } #=> [4, 8, 12, 16, 20]
#@end
@see [[m:Enumerable#filter]], [[m:Enumerable#map]]
#@end
--- grep(pattern) -> [object]
--- grep(pattern) {|item| ... } -> [object]
pattern === item が成立する要素を全て含んだ配列を返します。
ブロックとともに呼び出された時には条件の成立した要素に対して
それぞれブロックを評価し、その結果の配列を返します。
マッチする要素がひとつもなかった場合は空の配列を返します。
@param pattern 「===」メソッドを持つオブジェクトを指定します。
#@samplecode 例
['aa', 'bb', 'cc', 'dd', 'ee'].grep(/[bc]/) # => ["bb", "cc"]
Array.instance_methods.grep(/gr/) # => [:grep, :group_by]
#@end
@see [[m:Enumerable#select]]
@see [[m:Enumerable#grep_v]]
--- grep_v(pattern) -> [object]
--- grep_v(pattern) { |item| ... } -> [object]
[[m:Enumerable#grep]] のマッチの条件を逆にして、pattern === item が成立
しない要素を全て含んだ配列を返します。
@param pattern 「===」メソッドを持つオブジェクトを指定します。
#@samplecode 例
(1..10).grep_v 2..5 # => [1, 6, 7, 8, 9, 10]
res =(1..10).grep_v(2..5) { |v| v * 2 }
res # => [2, 12, 14, 16, 18, 20]
#@end
@see [[m:Enumerable#grep]]
@see [[m:Enumerable#reject]]
--- inject(init = self.first) {|result, item| ... } -> object
--- inject(sym) -> object
--- inject(init, sym) -> object
--- reduce(init = self.first) {|result, item| ... } -> object
--- reduce(sym) -> object
--- reduce(init, sym) -> object
リストのたたみこみ演算を行います。
最初に初期値 init と self の最初の要素を引数にブロックを実行します。
2 回目以降のループでは、前のブロックの実行結果と
self の次の要素を引数に順次ブロックを実行します。
そうして最後の要素まで繰り返し、最後のブロックの実行結果を返します。
要素が存在しない場合は init を返します。
初期値 init を省略した場合は、
最初に先頭の要素と 2 番目の要素をブロックに渡します。
また要素が 1 つしかなければブロックを実行せずに最初の要素を返します。
要素がなければブロックを実行せずに nil を返します。
@param init 最初の result の値です。任意のオブジェクトが渡せます。
@param sym ブロックの代わりに使われるメソッド名を表す [[c:Symbol]] オブジェクトを指定します。
実行結果に対して sym という名前のメソッドが呼ばれます。
#@samplecode 例
# 合計を計算する。
p [2, 3, 4, 5].inject {|result, item| result + item } #=> 14
# 自乗和を計算する。初期値をセットする必要がある。
p [2, 3, 4, 5].inject(0) {|result, item| result + item**2 } #=> 54
#@end
この式は以下のように書いても同じ結果が得られます。
#@samplecode 例
result = 0
[1, 2, 3, 4, 5].each {|v| result += v }
p result # => 15
p [1, 2, 3, 4, 5].inject(:+) #=> 15
p ["b", "c", "d"].inject("abbccddde", :squeeze) #=> "abcde"
#@end
--- member?(val) -> bool
--- include?(val) -> bool
val と == の関係にある要素を含むとき真を返します。
@param val 任意のオブジェクト
#@samplecode 例
[2, 4, 6].include? 2 #=> true
[2, 4, 6].include? 1 #=> false
[2, 4, 6].member? 2 #=> true
[2, 4, 6].member? 1 #=> false
#@end
--- max -> object | nil
--- max(n) -> Array
最大の要素、もしくは最大の n 要素が入った降順の配列を返します。
全要素が互いに <=> メソッドで比較できることを仮定しています。
引数を指定しない形式では要素が存在しなければ nil を返します。
引数を指定する形式では、空の配列を返します。
該当する要素が複数存在する場合、どの要素を返すかは不定です。
@param n 取得する要素数。
#@samplecode 例
a = %w(albatross dog horse)
a.max # => "horse"
a.max(2) # => ["horse", "dog"]
#@end
--- max {|a, b| ... } -> object | nil
--- max(n) {|a, b| ... } -> Array
ブロックの評価結果で各要素の大小判定を行い、最大の要素、もしくは最大の
n 要素が入った降順の配列を返します。
引数を指定しない形式では要素が存在しなければ nil を返します。
引数を指定する形式では、空の配列を返します。
ブロックの値は、a > b のとき正、
a == b のとき 0、a < b のとき負の整数を、期待しています。
該当する要素が複数存在する場合、どの要素を返すかは不定です。
@param n 取得する要素数。
@raise TypeError ブロックが整数以外を返したときに発生します。
#@samplecode 例
class Person
attr_reader :name, :age
def initialize(name, age)
@name = name
@age = age
end
end
people = [
Person.new("sato", 55),
Person.new("sato", 33),
Person.new("sato", 11),
Person.new("suzuki", 55),
Person.new("suzuki", 33),
Person.new("suzuki", 11),
Person.new("tanaka", 55),
Person.new("tanaka", 33),
Person.new("tanaka", 11)
]
# 年齢が最大、名前が最小
people.max { |x, y| (x.age <=> y.age).nonzero? || y.name <=> x.name }
# => #<Person:0x007fc54b0240a0 @name="sato", @age=55>
people.max(2) { |x, y| (x.age <=> y.age).nonzero? || y.name <=> x.name }
# => [#<Person:0x007fc54b0240a0 @name="sato", @age=55>, #<Person:0x007fc54c033ea0 @name="suzuki", @age=55>]
#@end
--- max_by -> Enumerator
--- max_by(n) -> Enumerator
--- max_by {|item| ... } -> object | nil
--- max_by(n) {|item| ... } -> Array
各要素を順番にブロックに渡して実行し、
その評価結果を <=> で比較して、
最大であった値に対応する元の要素、もしくは最大の n 要素が降順で入った配列を返します。
引数を指定しない形式では要素が存在しなければ nil を返します。
引数を指定する形式では、空の配列を返します。
該当する要素が複数存在する場合、どの要素を返すかは不定です。
[[m:Enumerable#max]] と [[m:Enumerable#max_by]] の
違いは [[m:Enumerable#sort]] と [[m:Enumerable#sort_by]] の違いと同じです。
ブロックを省略した場合は [[c:Enumerator]] を返します。
@param n 取得する要素数。
#@samplecode 例
a = %w(albatross dog horse)
a.max_by # => #<Enumerator: ["albatross", "dog", "horse"]:max_by>
a.max_by { |x| x.length } # => "albatross"
#@end
#@samplecode 例
a = %w[albatross dog horse]
a.max_by(2) # => #<Enumerator: ["albatross", "dog", "horse"]:max_by(2)>
a.max_by(2) {|x| x.length } # => ["albatross", "horse"]
#@end
#@samplecode 例: enum.max_by(n)は、重み付きランダムサンプリングを実装するために使用できます。次の実装例は、Enumerable#wsampleを使用します。
module Enumerable
# weighted random sampling.
#
# Pavlos S. Efraimidis, Paul G. Spirakis
# Weighted random sampling with a reservoir
# Information Processing Letters
# Volume 97, Issue 5 (16 March 2006)
def wsample(n)
self.max_by(n) {|v| rand ** (1.0/yield(v)) }
end
end
e = (-20..20).to_a*10000
a = e.wsample(20000) {|x|
Math.exp(-(x/5.0)**2) # normal distribution
}
# a is 20000 samples from e.
p a.length #=> 20000
h = a.group_by {|x| x }
-10.upto(10) {|x| puts "*" * (h[x].length/30.0).to_i if h[x] }
#=> *
# ***
# ******
# ***********
# ******************
# *****************************
# *****************************************
# ****************************************************
# ***************************************************************
# ********************************************************************
# ***********************************************************************
# ***********************************************************************
# **************************************************************
# ****************************************************
# ***************************************
# ***************************
# ******************
# ***********
# *******
# ***
# *
#@end
@see [[m:Enumerable#sort_by]]
--- min -> object | nil
--- min(n) -> Array
最小の要素、もしくは最小の n 要素が昇順で入った配列を返します。
全要素が互いに <=> メソッドで比較できることを仮定しています。
引数を指定しない形式では要素が存在しなければ nil を返します。
引数を指定する形式では、空の配列を返します。
該当する要素が複数存在する場合、どの要素を返すかは不定です。
@param n 取得する要素数。
#@samplecode 例
a = %w(albatross dog horse)
a.min # => "albatross"
a.min(2) # => ["albatross", "dog"]
#@end
--- min {|a, b| ... } -> object | nil
--- min(n) {|a, b| ... } -> Array
ブロックの評価結果で各要素の大小判定を行い、最小の要素、もしくは最小の
n 要素が昇順で入った配列を返します。
引数を指定しない形式では要素が存在しなければ nil を返します。
引数を指定する形式では、空の配列を返します。
ブロックの値は、a > b のとき正、a == b のとき 0、
a < b のとき負の整数を、期待しています。
該当する要素が複数存在する場合、どの要素を返すかは不定です。
@param n 取得する要素数。
#@samplecode 例
class Person
attr_reader :name, :age
def initialize(name, age)
@name = name
@age = age
end
end
people = [
Person.new("sato", 55),
Person.new("sato", 33),
Person.new("sato", 11),
Person.new("suzuki", 55),
Person.new("suzuki", 33),
Person.new("suzuki", 11),
Person.new("tanaka", 55),
Person.new("tanaka", 33),
Person.new("tanaka", 11)
]
# 年齢が最小、名前が最大
people.min { |x, y| (x.age <=> y.age).nonzero? || y.name <=> x.name }
# => #<Person:0x007fd6f0824190 @name="tanaka", @age=11>
people.min(2) { |x, y| (x.age <=> y.age).nonzero? || y.name <=> x.name }
# => [#<Person:0x007fb5899ef4a8 @name="tanaka", @age=11>, #<Person:0x007fb5899ef728 @name="suzuki", @age=11>]
#@end
@raise TypeError ブロックが整数以外を返したときに発生します。
--- min_by -> Enumerator
--- min_by(n) -> Enumerator
--- min_by {|item| ... } -> object | nil
--- min_by(n) {|item| ... } -> Array
各要素を順番にブロックに渡して評価し、
その評価結果を <=> で比較して、
最小であった値に対応する元の要素、もしくは最小の n 要素が昇順で入った配列を返します。
引数を指定しない形式では要素が存在しなければ nil を返します。
引数を指定する形式では、空の配列を返します。
該当する要素が複数存在する場合、どの要素を返すかは不定です。
ブロックを省略した場合は [[c:Enumerator]] を返します。
[[m:Enumerable#min]] と [[m:Enumerable#min_by]] の
違いは [[m:Enumerable#sort]] と [[m:Enumerable#sort_by]] の違いと同じです。
@param n 取得する要素数。
#@samplecode 例
a = %w(albatross dog horse)
a.min_by # => #<Enumerator: ["albatross", "dog", "horse"]:min_by>
a.min_by { |x| x.length } # => "dog"
a.min_by(2) # => #<Enumerator: ["albatross", "dog", "horse"]:min_by(2)>
a.min_by(2) {|x| x.length } # => ["dog", "horse"]
#@end
@see [[m:Enumerable#sort_by]]
--- partition -> Enumerator
--- partition {|item| ... } -> [[object], [object]]
各要素を、ブロックの条件を満たす要素と満たさない要素に分割します。
各要素に対してブロックを評価して、その値が真であった要素の配列と、
偽であった要素の配列の 2 つを配列に入れて返します。
ブロックを省略した場合は [[c:Enumerator]] を返します。
#@samplecode 例
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0].partition {|i| i % 3 == 0 }
#=> [[9, 6, 3, 0], [10, 8, 7, 5, 4, 2, 1]]
#@end
--- reject -> Enumerator
--- reject {|item| ... } -> [object]
各要素に対してブロックを評価し、
その値が偽であった要素を集めた新しい配列を返します。
条件を反転させた select です。
ブロックを省略した場合は [[c:Enumerator]] を返します。
#@samplecode 例
# 偶数を除外する (奇数を集める)
(1..6).reject {|i| i % 2 == 0 } # => [1, 3, 5]
#@end
@see [[m:Enumerable#select]], [[m:Array#reject]]
@see [[m:Enumerable#grep_v]]
--- sort -> [object]
--- sort {|a, b| ... } -> [object]
全ての要素を昇順にソートした配列を生成して返します。
ブロックなしのときは <=> メソッドを要素に対して呼び、
その結果をもとにソートします。
<=> 以外でソートしたい場合は、ブロックを指定します。
この場合、ブロックの評価結果を元にソートします。
ブロックの値は、a > b のとき正、a == b のとき 0、
a < b のとき負の整数を、期待しています。
ブロックが整数以外を返したときは例外 [[c:TypeError]] が発生します。
Enumerable#sort は安定ではありません (unstable sort)。
安定なソートが必要な場合は [[m:Enumerable#sort_by]] を使って工夫する必要があります。
詳しくは [[m:Enumerable#sort_by]] の項目を参照してください。
※ 比較結果が同じ要素は元の順序通りに並ぶソートを
「安定なソート (stable sort)」と言います。
#@samplecode 例
%w(rhea kea flea).sort # => ["flea", "kea", "rhea"]
(1..10).sort { |a, b| b <=> a } # => [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
#@end
@see [[m:Enumerable#sort_by]]
--- sort_by -> Enumerator
--- sort_by {|item| ... } -> [object]
ブロックの評価結果を <=> メソッドで比較することで、self を昇
順にソートします。ソートされた配列を新たに生成して返します。
つまり、以下とほぼ同じ動作をします。
#@samplecode 例
class Array
def sort_by
self.map {|i| [yield(i), i] }.
sort {|a, b| a[0] <=> b[0] }.
map {|i| i[1]}
end
end
#@end
[[m:Enumerable#sort]] と比較して sort_by が優れている点として、
比較条件が複雑な場合の速度が挙げられます。
sort_by を使わない以下の例では比較を行う度に downcase が実行されます。
従って downcase の実行速度が遅ければ sort の速度が致命的に低下します。
#@samplecode
p ["BAR", "FOO", "bar", "foo"].sort {|a, b| a.downcase <=> b.downcase }
#@end
一方、次のように sort_by を使うと downcase の実行回数は要素数と同じです。
つまり、その部分の実行時間は O(n) のオーダーです。
#@samplecode
p ["BAR", "FOO", "bar", "foo"].sort_by {|v| v.downcase }
#@end
以下の、実行回数の検証結果を参照してみてください。
#@samplecode
class Integer
def count
$n += 1
self
end
end
ary = []
1.upto(1000) {|v| ary << rand(v) }
$n = 0
ary.sort {|a,b| a.count <=> b.count }
p $n # => 18200
$n = 0
ary.sort_by {|v| v.count }
p $n # => 1000
#@end
Enumerable#sort_by は安定ではありません (unstable sort)。
ただし、sort_by を以下のように使うと安定なソートを実装できます。
#@samplecode
i = 0
ary.sort_by {|v| [v, i += 1] }
#@end
※ 比較結果が同じ要素は元の順序通りに並ぶソートを
「安定なソート (stable sort)」と言います。
ブロックを省略した場合は [[c:Enumerator]] を返します。
@see [[m:Enumerable#sort]]
--- to_a(*args) -> [object]
--- entries(*args) -> [object]
全ての要素を含む配列を返します。
@param args each の呼び出し時に引数として渡されます。
#@samplecode 例
(1..7).to_a #=> [1, 2, 3, 4, 5, 6, 7]
{ 'a'=>1, 'b'=>2, 'c'=>3 }.to_a #=> [["a", 1], ["b", 2], ["c", 3]]
require 'prime'
Prime.entries 10 #=> [2, 3, 5, 7]
#@end
--- to_h(*args) -> Hash
#@since 2.6.0
--- to_h(*args) { ... } -> Hash
#@end
self を [key, value] のペアの配列として解析した結果を [[c:Hash]] にして
返します。
@param args each の呼び出し時に引数として渡されます。
#@samplecode 例
%i[hello world].each_with_index.to_h # => {:hello => 0, :world => 1}
#@end
#@since 2.6.0
ブロックを指定すると各要素でブロックを呼び出し、
その結果をペアとして使います。
#@samplecode ブロック付きの例
(1..5).to_h {|x| [x, x ** 2]} # => {1=>1, 2=>4, 3=>9, 4=>16, 5=>25}
#@end
#@end
--- zip(*lists) -> [[object]]
--- zip(*lists) {|v1, v2, ...| ...} -> nil
self と引数に渡した配列の各要素からなる配列の配列を生成して返します。
生成される配列の要素数は self の要素数と同じです。
ブロック付きで呼び出した場合は、
self と引数に渡した配列の各要素を順番にブロックに渡します。
@param lists 配列を指定します。配列でない場合は to_ary メソッドにより配列に変換します。
to_ary メソッドが無い場合は each を試します。
#@samplecode 例
p (1..3).zip([4,5,6], [7,8,9])
# => [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
p (1..2).zip([:a,:b,:c], [:A,:B,:C,:D])
# => [[1, :a, :A], [2, :b, :B]]
p (1..5).zip([:a,:b,:c], [:A,:B,:C,:D])
# => [[1, :a, :A], [2, :b, :B],
# [3, :c, :C], [4, nil, :D], [5, nil, nil]]
#@end
#@samplecode 例
p [1,2,3].zip([4,5,6], [7,8,9]) {|ary|
p ary
}
# => [1, 4, 7]
# [2, 5, 8]
# [3, 6, 9]
# nil
#@end
--- each_slice(n) -> Enumerator
--- each_slice(n) {|list| ... } -> nil
n 要素ずつブロックに渡して繰り返します。
要素数が n で割り切れないときは、最後の回だけ要素数が減ります。
ブロックを省略した場合は
n 要素ずつ繰り返す [[c:Enumerator]] を返します。
@param n 区切る要素数を示す整数です。
#@samplecode 例
(1..10).each_slice(3) {|a| p a}
# => [1, 2, 3]
# [4, 5, 6]
# [7, 8, 9]
# [10]
#@end
@see [[m:Enumerable#each_cons]]
--- each_cons(n) -> Enumerator
--- each_cons(n) {|list| ... } -> nil
要素を重複ありで n 要素ずつに区切り、
ブロックに渡して繰り返します。
ブロックを省略した場合は重複ありで
n 要素ずつ繰り返す [[c:Enumerator]] を返します。
@param n ブロックに渡す要素の数です。正の整数を与えます。
要素数より大きな数を与えると、ブロックは一度も実行されません。
#@samplecode 例
(1..10).each_cons(3){|v| p v }
# => [1, 2, 3]
# [2, 3, 4]
# [3, 4, 5]
# [4, 5, 6]
# [5, 6, 7]
# [6, 7, 8]
# [7, 8, 9]
# [8, 9, 10]
#@end
@see [[m:Enumerable#each_slice]]
--- count -> Integer
--- count(item) -> Integer
--- count {|obj| ... } -> Integer
レシーバの要素数を返します。
引数を指定しない場合は、レシーバの要素数を返します。
このとき、要素数を一つずつカウントします。
引数を一つ指定した場合は、レシーバの要素のうち引数に一致するものの
個数をカウントして返します(一致は == で判定します)。
ブロックを指定した場合は、ブロックを評価して真になった要素の個数を
カウントして返します。
@param item カウント対象となる値。
#@samplecode 例
enum = [1, 2, 4, 2].each
enum.count # => 4
enum.count(2) # => 2
enum.count{|x|x%2==0} # => 3
#@end
@see [[m:Array#count]]
--- cycle(n=nil) -> Enumerator
--- cycle(n=nil) {|obj| ... } -> object | nil
Enumerable オブジェクトの各要素を n 回 or 無限回(n=nil)繰り返し
ブロックを呼びだします。
n に 0 もしくは負の値を渡した場合は何もしません。
繰り返しが最後まで終了した場合(つまりbreakなどで中断しなかった場合)
は nil を返します。
このメソッドは内部の配列に各要素を保存しておくため、
一度 Enumerable の終端に到達した後に自分自身を変更しても
このメソッドの動作に影響を与えません。
#@samplecode 例
a = ["a", "b", "c"]
a.cycle {|x| puts x } # print, a, b, c, a, b, c,.. forever.
a.cycle(2) {|x| puts x } # print, a, b, c, a, b, c.
#@end
ブロックを省略した場合は、n 回 or 無限回 enum の各要素を
繰り返す [[c:Enumerator]] を返します。
@return ブロックを指定しなかった場合は、[[c:Enumerator]] を返します。
レシーバが空の場合は nil を返します。
--- drop(n) -> Array
Enumerable オブジェクトの先頭の n 要素を捨てて、
残りの要素を配列として返します。
@param n 捨てる要素数。
#@samplecode 例
e = [1, 2, 3, 4, 5, 0].each
e.drop(3) # => [4, 5, 0]
#@end
@see [[m:Array#drop]]
--- drop_while -> Enumerator
--- drop_while {|element| ... } -> Array
ブロックを評価して最初に偽となった要素の手前の要素まで捨て、
残りの要素を配列として返します。
ブロックを指定しなかった場合は、[[c:Enumerator]] を返します。
#@samplecode 例
a = [1, 2, 3, 4, 5, 0]
a.drop_while {|i| i < 3 } # => [3, 4, 5, 0]
#@end
--- find_index(val) -> Integer | nil
--- find_index {|obj| ... } -> Integer | nil
--- find_index -> Enumerator
条件に一致する最初の要素の位置を返します。
@param val 位置を知りたいオブジェクトを指定します。
指定された val と == で等しい最初の要素の位置を返します。
等しい要素がひとつもなかった場合は nil を返します。
#@samplecode 例
(1..10).find_index(11) #=> nil
(1..10).find_index(2) #=> 1
#@end
ブロックが与えられた場合には、各要素を引数として先頭から順にブロックを実行し、
ブロックが真を返した最初の要素の位置を返します。
一つも真にならなかった場合は nil を返します。
#@samplecode 例
(1..10).find_index {|i| i % 5 == 0 and i % 7 == 0 } #=> nil
(1..100).find_index {|i| i % 5 == 0 and i % 7 == 0 } #=> 34
#@end
引数、ブロックのどちらも与えられなかった場合は、
[[c:Enumerator]] のインスタンスを返します。
--- first -> object | nil
--- first(n) -> Array
Enumerable オブジェクトの最初の要素、もしくは最初の n 要素を返します。
Enumerable オブジェクトが空の場合、引数を指定しない形式では nil を返します。
引数を指定する形式では、空の配列を返します。
@param n 取得する要素数。
#@samplecode 例
e = "abcd".each_byte
e.first #=> 97
e.first(2) #=> [97,98]
e = "".each_byte
e.first #=> nil
e.first(2) #=> []
#@end
--- group_by -> Enumerator
--- group_by {|obj| ... } -> Hash
ブロックを評価した結果をキー、対応する要素の配列を値とするハッシュを返します。
#@samplecode 例
(1..6).group_by {|i| i%3} #=> {0=>[3, 6], 1=>[1, 4], 2=>[2, 5]}
#@end
ブロックを省略した場合は [[c:Enumerator]] を返します。
--- minmax -> [object, object]
--- minmax{|a, b| ... } -> [object, object]
Enumerable オブジェクトの各要素のうち最小の要素と最大の要素を
要素とするサイズ 2 の配列を返します。
該当する要素が複数存在する場合、どの要素を返すかは不定です。
一つ目の形式は、Enumerable オブジェクトのすべての要素が Comparable を
実装していることを仮定しています。二つ目の形式では、要素同士の比較を
ブロックを用いて行います。
#@samplecode 例
a = %w(albatross dog horse)
a.minmax #=> ["albatross", "horse"]
a.minmax{|a,b| a.length <=> b.length } #=> ["dog", "albatross"]
[].minmax # => [nil, nil]
#@end
#@since 2.7.0
@see [[m:Enumerable#sort]], [[m:Array#minmax]]
#@else
@see [[m:Enumerable#sort]]
#@end
--- minmax_by -> Enumerator
--- minmax_by {|obj| ... } -> [object, object]
Enumerable オブジェクトの各要素をブロックに渡して評価し、その結果を <=> で比較して
最小の要素と最大の要素を要素とするサイズ 2 の配列を返します。
該当する要素が複数存在する場合、どの要素を返すかは不定です。
[[m:Enumerable#minmax]] と [[m:Enumerable#minmax_by]] の
違いは sort と sort_by の違いと同じです。
詳細は [[m:Enumerable#sort_by]] を参照してください。
#@samplecode 例
a = %w(albatross dog horse)
a.minmax_by {|x| x.length } #=> ["dog", "albatross"]
[].minmax_by{} # => [nil, nil]
#@end
ブロックを省略した場合は [[c:Enumerator]] を返します。
@see [[m:Enumerable#sort_by]]
--- none? -> bool
--- none?{|obj| ... } -> bool
#@since 2.5.0
--- none?(pattern) -> bool
#@end
ブロックを指定しない場合は、 Enumerable オブジェクトのすべての
要素が偽であれば真を返します。そうでなければ偽を返します。
ブロックを指定した場合は、Enumerable オブジェクトのすべての要素を