Ruby_Array_60

この記事は、以下のドキュメントを改変(自分なりに整理)して利用しています。

class Array (Ruby 3.1 リファレンスマニュアル)

インスタンスメソッド

transpose -> Array
  • 自身を行列と見立てて、行列の転置を行い、転置した配列を生成して返す
    • 空の配列に対しては空の配列を生成して返す
  • 一次元の配列に対してはTypeErrorが、各要素のサイズが不揃いな配列に対してはIndexErrorが発生する
# 1 2
# 3 4
# 5 6
# ↓
# 1 3 5
# 2 4 6

irb(main):001:0> arr = [[1, 2], [3, 4], [5, 6]]
=> [[1, 2], [3, 4], [5, 6]]

irb(main):002:0> arr.transpose
=> [[1, 3, 5], [2, 4, 6]]

irb(main):003:0> arr
=> [[1, 2], [3, 4], [5, 6]]

irb(main):004:0> arr.transpose.transpose
=> [[1, 2], [3, 4], [5, 6]]

irb(main):005:0> [].transpose
=> []
irb(main):001:0> arr = [['a', 'b'], ['c', 'd']]
=> [["a", "b"], ["c", "d"]]

irb(main):002:0> brr = arr.transpose
=> [["a", "c"], ["b", "d"]]

irb(main):003:0> arr[0][0].capitalize!
=> "A"

irb(main):004:0> arr
=> [["A", "b"], ["c", "d"]]

irb(main):005:0> brr
=> [["A", "c"], ["b", "d"]]
irb(main):001:0> [1, 2, 3].transpose
(irb):1:in `transpose': no implicit conversion of Integer into Array (TypeError)
        from (irb):1:in `<main>'                                            
        from /Users/mfham/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/irb-1.4.1/exe/irb:11:in `<top (required)>'
        from /Users/mfham/.rbenv/versions/3.1.0/bin/irb:25:in `load'        
        from /Users/mfham/.rbenv/versions/3.1.0/bin/irb:25:in `<main>'  

irb(main):002:0> [[1, 2], [3, 4, 5]].transpose
(irb):2:in `transpose': element size differs (3 should be 2) (IndexError)
        from (irb):2:in `<main>'                                                         
        from /Users/mfham/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/irb-1.4.1/exe/irb:11:in `<top (required)>'
        from /Users/mfham/.rbenv/versions/3.1.0/bin/irb:25:in `load'                     
        from /Users/mfham/.rbenv/versions/3.1.0/bin/irb:25:in `<main>' 
union(*other_arrays) -> Array
  • 集合の和演算。重複する要素は取り除かれる
    • 重複判定はObject#eql?とObject#hashによって行われる
irb(main):001:0> [1, 'a', 'b'].union([1, 1.0, '1', 'a', 'A'])
=> [1, "a", "b", 1.0, "1", "A"]

irb(main):002:0> [1, 'a', 'b'].union([1, 1.0, '1', 'a', 'A'], ['c'])
=> [1, "a", "b", 1.0, "1", "A", "c"]

irb(main):003:0> [1, 'a', 'b'].union([])
=> [1, "a", "b"]

irb(main):004:0> [1, 'a', 'b'].union
=> [1, "a", "b"]
irb(main):001:0> v = 'a'
=> "a"

irb(main):002:0> [v].union([v])
=> ["a"]

irb(main):003:0> [v].union([v.capitalize!])
=> ["A"]

irb(main):004:0> ['a'].union(['a'.capitalize!])
=> ["a", "A"]
[7] pry(main)> show-source Array#union

From: array.c (C Method):
Owner: Array
Visibility: public
Signature: union(*arg1)
Number of lines: 29

static VALUE
rb_ary_union_multi(int argc, VALUE *argv, VALUE ary)
{
    int i;
    long sum;
    VALUE hash, ary_union;

    sum = RARRAY_LEN(ary);
    for (i = 0; i < argc; i++) {
        argv[i] = to_ary(argv[i]);
        sum += RARRAY_LEN(argv[i]);
    }

    if (sum <= SMALL_ARRAY_LEN) {
        ary_union = rb_ary_new();

        rb_ary_union(ary_union, ary);
        for (i = 0; i < argc; i++) rb_ary_union(ary_union, argv[i]);

        return ary_union;
    }

    hash = ary_make_hash(ary);
    for (i = 0; i < argc; i++) rb_ary_union_hash(hash, argv[i]);

    ary_union = rb_hash_values(hash);
    ary_recycle_hash(hash);
    return ary_union;
}

[8] pry(main)> show-source Array#|

From: array.c (C Method):
Owner: Array
Visibility: public
Signature: |(arg1)
Number of lines: 20

static VALUE
rb_ary_or(VALUE ary1, VALUE ary2)
{
    VALUE hash, ary3;

    ary2 = to_ary(ary2);
    if (RARRAY_LEN(ary1) + RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {
        ary3 = rb_ary_new();
        rb_ary_union(ary3, ary1);
        rb_ary_union(ary3, ary2);
        return ary3;
    }

    hash = ary_make_hash(ary1);
    rb_ary_union_hash(hash, ary2);

    ary3 = rb_hash_values(hash);
    ary_recycle_hash(hash);
    return ary3;
}

# memo
# Array#unionとArray#|の内部実装が若干違う
# Array#unionは配列を複数受け取るからそこの対応の差なのかな?内部実装はまだ読み解いていない