@@ -365,14 +365,91 @@ def headers
365
365
end
366
366
end
367
367
368
+ # :call-seq:
369
+ # table[n] -> row
370
+ # table[range] -> array_of_rows
371
+ # table[header] -> array_of_fields
368
372
#
369
- # In the default mixed mode, this method returns rows for index access and
370
- # columns for header access. You can force the index association by first
371
- # calling by_col!() or by_row!().
373
+ # Returns data from the table; does not modify the table.
374
+ #
375
+ # ---
376
+ #
377
+ # The expression <tt>table[n]</tt>, where +n+ is a non-negative \Integer,
378
+ # returns the +n+th row of the table, if that row exists,
379
+ # and if the access mode is <tt>:row</tt> or <tt>:col_or_row</tt>:
380
+ # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
381
+ # table = CSV.parse(source, headers: true)
382
+ # table.by_row! # => #<CSV::Table mode:row row_count:4>
383
+ # table[1] # => #<CSV::Row "Name":"bar" "Value":"1">
384
+ # table.by_col_or_row! # => #<CSV::Table mode:col_or_row row_count:4>
385
+ # table[1] # => #<CSV::Row "Name":"bar" "Value":"1">
386
+ #
387
+ # Counts backward from the last row if +n+ is negative:
388
+ # table[-1] # => #<CSV::Row "Name":"baz" "Value":"2">
389
+ #
390
+ # Returns +nil+ if +n+ is too large or too small:
391
+ # table[4] # => nil
392
+ # table[-4] => nil
393
+ #
394
+ # Raises an exception if the access mode is <tt>:row</tt>
395
+ # and +n+ is not an
396
+ # {Integer-convertible object}[https://docs.ruby-lang.org/en/master/implicit_conversion_rdoc.html#label-Integer-Convertible+Objects].
397
+ # table.by_row! # => #<CSV::Table mode:row row_count:4>
398
+ # # Raises TypeError (no implicit conversion of String into Integer):
399
+ # table['Name']
400
+ #
401
+ # ---
402
+ #
403
+ # The expression <tt>table[range]</tt>, where +range+ is a Range object,
404
+ # returns rows from the table, beginning at row <tt>range.first</tt>,
405
+ # if those rows exist, and if the access mode is <tt>:row</tt> or <tt>:col_or_row</tt>:
406
+ # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
407
+ # table = CSV.parse(source, headers: true)
408
+ # table.by_row! # => #<CSV::Table mode:row row_count:4>
409
+ # rows = table[1..2] # => #<CSV::Row "Name":"bar" "Value":"1">
410
+ # rows # => [#<CSV::Row "Name":"bar" "Value":"1">, #<CSV::Row "Name":"baz" "Value":"2">]
411
+ # table.by_col_or_row! # => #<CSV::Table mode:col_or_row row_count:4>
412
+ # rows = table[1..2] # => #<CSV::Row "Name":"bar" "Value":"1">
413
+ # rows # => [#<CSV::Row "Name":"bar" "Value":"1">, #<CSV::Row "Name":"baz" "Value":"2">]
414
+ #
415
+ # If there are too few rows, returns all from <tt>range.first</tt> to the end:
416
+ # rows = table[1..50] # => #<CSV::Row "Name":"bar" "Value":"1">
417
+ # rows # => [#<CSV::Row "Name":"bar" "Value":"1">, #<CSV::Row "Name":"baz" "Value":"2">]
418
+ #
419
+ # Special case: if <tt>range.start == table.size</tt>, returns an empty \Array:
420
+ # table[table.size..50] # => []
372
421
#
373
- # Columns are returned as an Array of values. Altering that Array has no
374
- # effect on the table.
422
+ # If <tt>range.end</tt> is negative, calculates the ending index from the end:
423
+ # rows = table[0..-1]
424
+ # rows # => [#<CSV::Row "Name":"foo" "Value":"0">, #<CSV::Row "Name":"bar" "Value":"1">, #<CSV::Row "Name":"baz" "Value":"2">]
375
425
#
426
+ # If <tt>range.start</tt> is negative, calculates the starting index from the end:
427
+ # rows = table[-1..2]
428
+ # rows # => [#<CSV::Row "Name":"baz" "Value":"2">]
429
+ #
430
+ # If <tt>range.start</tt> is larger than <tt>table.size</tt>, returns +nil+:
431
+ # table[4..4] # => nil
432
+ #
433
+ # ---
434
+ #
435
+ # The expression <tt>table[header]</tt>, where +header+ is a \String,
436
+ # returns column values (\Array of \Strings) if the column exists
437
+ # and if the access mode is <tt>:col</tt> or <tt>:col_or_row</tt>:
438
+ # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
439
+ # table = CSV.parse(source, headers: true)
440
+ # table.by_col! # => #<CSV::Table mode:col row_count:4>
441
+ # table['Name'] # => ["foo", "bar", "baz"]
442
+ # table.by_col_or_row! # => #<CSV::Table mode:col_or_row row_count:4>
443
+ # col = table['Name']
444
+ # col # => ["foo", "bar", "baz"]
445
+ #
446
+ # Modifying the returned column values does not modify the table:
447
+ # col[0] = 'bat'
448
+ # col # => ["bat", "bar", "baz"]
449
+ # table['Name'] # => ["foo", "bar", "baz"]
450
+ #
451
+ # Returns an \Array of +nil+ values if there is no such column:
452
+ # table['Nosuch'] # => [nil, nil, nil]
376
453
def []( index_or_header )
377
454
if @mode == :row or # by index
378
455
( @mode == :col_or_row and ( index_or_header . is_a? ( Integer ) or index_or_header . is_a? ( Range ) ) )
0 commit comments