@@ -358,17 +358,34 @@ def []=(*args)
358
358
359
359
#
360
360
# :call-seq:
361
- # <<( field )
362
- # <<( header_and_field_array )
363
- # <<( header_and_field_hash )
361
+ # row << [header, value] -> self
362
+ # row << hash -> self
363
+ # row << value -> self
364
364
#
365
- # If a two-element Array is provided, it is assumed to be a header and field
366
- # and the pair is appended. A Hash works the same way with the key being
367
- # the header and the value being the field. Anything else is assumed to be
368
- # a lone field which is appended with a +nil+ header.
365
+ # Adds a field to +self+; returns +self+:
369
366
#
370
- # This method returns the row for chaining.
367
+ # If the argument is a 2-element \Array <tt>[header, value]</tt>,
368
+ # a field is added with the given +header+ and +value+:
369
+ # source = "Name,Name,Name\nFoo,Bar,Baz\n"
370
+ # table = CSV.parse(source, headers: true)
371
+ # row = table[0]
372
+ # row << ['NAME', 'Bat']
373
+ # row # => #<CSV::Row "Name":"Foo" "Name":"Bar" "Name":"Baz" "NAME":"Bat">
374
+ #
375
+ # If the argument is a \Hash, each <tt>key-value</tt> pair is added
376
+ # as a field with header +key+ and value +value+.
377
+ # source = "Name,Name,Name\nFoo,Bar,Baz\n"
378
+ # table = CSV.parse(source, headers: true)
379
+ # row = table[0]
380
+ # row << {NAME: 'Bat', name: 'Bam'}
381
+ # row # => #<CSV::Row "Name":"Foo" "Name":"Bar" "Name":"Baz" NAME:"Bat" name:"Bam">
371
382
#
383
+ # Otherwise, the given +value+ is added as a field with no header.
384
+ # source = "Name,Name,Name\nFoo,Bar,Baz\n"
385
+ # table = CSV.parse(source, headers: true)
386
+ # row = table[0]
387
+ # row << 'Bag'
388
+ # row # => #<CSV::Row "Name":"Foo" "Name":"Bar" "Name":"Baz" nil:"Bag">
372
389
def <<( arg )
373
390
if arg . is_a? ( Array ) and arg . size == 2 # appending a header and name
374
391
@row << arg
@@ -381,13 +398,15 @@ def <<(arg)
381
398
self # for chaining
382
399
end
383
400
401
+ # :call-seq:
402
+ # row.push(*values) ->self
384
403
#
385
- # A shortcut for appending multiple fields. Equivalent to :
386
- #
387
- # args.each { |arg| csv_row << arg }
388
- #
389
- # This method returns the row for chaining.
390
- #
404
+ # Appends each of the given +values+ to +self+ as a field; returns +self+ :
405
+ # source = "Name,Name,Name\nFoo,Bar,Baz\n"
406
+ # table = CSV.parse(source, headers: true)
407
+ # row = table[0]
408
+ # row.push('Bat', 'Bam')
409
+ # row # => #<CSV::Row "Name":"Foo" "Name":"Bar" "Name":"Baz" nil:"Bat" nil:"Bam">
391
410
def push ( *args )
392
411
args . each { |arg | self << arg }
393
412
@@ -396,14 +415,39 @@ def push(*args)
396
415
397
416
#
398
417
# :call-seq:
399
- # delete( header )
400
- # delete( header, offset )
401
- # delete( index )
418
+ # delete(index) -> [header, value] or nil
419
+ # delete(header) -> [header, value] or empty_array
420
+ # delete(header, offset) -> [header, value] or empty_array
421
+ #
422
+ # Removes a specified field from +self+; returns the 2-element \Array
423
+ # <tt>[header, value]</tt> if the field exists.
402
424
#
403
- # Removes a pair from the row by +header+ or +index+. The pair is
404
- # located as described in CSV::Row.field(). The deleted pair is returned,
405
- # or +nil+ if a pair could not be found.
425
+ # If an \Integer argument +index+ is given,
426
+ # removes and returns the field at offset +index+,
427
+ # or returns +nil+ if the field does not exist:
428
+ # source = "Name,Name,Name\nFoo,Bar,Baz\n"
429
+ # table = CSV.parse(source, headers: true)
430
+ # row = table[0]
431
+ # row.delete(1) # => ["Name", "Bar"]
432
+ # row.delete(50) # => nil
406
433
#
434
+ # Otherwise, if the single argument +header+ is given,
435
+ # removes and returns the first-found field with the given header,
436
+ # of returns a new empty \Array if the field does not exist:
437
+ # source = "Name,Name,Name\nFoo,Bar,Baz\n"
438
+ # table = CSV.parse(source, headers: true)
439
+ # row = table[0]
440
+ # row.delete('Name') # => ["Name", "Foo"]
441
+ # row.delete('NAME') # => []
442
+ #
443
+ # If argument +header+ and \Integer argument +offset+ are given,
444
+ # removes and returns the first-found field with the given header
445
+ # whose +index+ is at least as large as +offset+:
446
+ # source = "Name,Name,Name\nFoo,Bar,Baz\n"
447
+ # table = CSV.parse(source, headers: true)
448
+ # row = table[0]
449
+ # row.delete('Name', 1) # => ["Name", "Bar"]
450
+ # row.delete('NAME', 1) # => []
407
451
def delete ( header_or_index , minimum_index = 0 )
408
452
if header_or_index . is_a? Integer # by index
409
453
@row . delete_at ( header_or_index )
@@ -414,15 +458,21 @@ def delete(header_or_index, minimum_index = 0)
414
458
end
415
459
end
416
460
461
+ # :call-seq:
462
+ # row.delete_if {|header, value| ... } -> self
417
463
#
418
- # The provided +block+ is passed a header and field for each pair in the row
419
- # and expected to return +true+ or +false+, depending on whether the pair
420
- # should be deleted.
421
- #
422
- # This method returns the row for chaining.
464
+ # Removes fields from +self+ as selected by the block; returns +self+.
423
465
#
424
- # If no block is given, an Enumerator is returned.
466
+ # Removes each field for which the block returns a truthy value:
467
+ # source = "Name,Name,Name\nFoo,Bar,Baz\n"
468
+ # table = CSV.parse(source, headers: true)
469
+ # row = table[0]
470
+ # row.delete_if {|header, value| value.start_with?('B') } # => true
471
+ # row # => #<CSV::Row "Name":"Foo">
472
+ # row.delete_if {|header, value| header.start_with?('B') } # => false
425
473
#
474
+ # If no block is given, returns a new Enumerator:
475
+ # row.delete_if # => #<Enumerator: #<CSV::Row "Name":"Foo">:delete_if>
426
476
def delete_if ( &block )
427
477
return enum_for ( __method__ ) { size } unless block_given?
428
478
@@ -431,14 +481,52 @@ def delete_if(&block)
431
481
self # for chaining
432
482
end
433
483
484
+ # :call-seq:
485
+ # self.fields(*specifiers)
434
486
#
435
- # This method accepts any number of arguments which can be headers, indices,
436
- # Ranges of either, or two-element Arrays containing a header and offset.
437
- # Each argument will be replaced with a field lookup as described in
438
- # CSV::Row.field().
487
+ # Returns field values per the given +specifiers+, which may be any mixture of:
488
+ # - \Integer index.
489
+ # - \Range of \Integer indexes.
490
+ # - 2-element \Array containing a header and offset.
491
+ # - Header.
492
+ # - \Range of headers.
439
493
#
440
- # If called with no arguments, all fields are returned.
494
+ # For +specifier+ in one of the first four cases above,
495
+ # returns the result of <tt>self.field(specifier)</tt>; see #field.
496
+ #
497
+ # Although there may be any number of +specifiers+,
498
+ # the examples here will illustrate one at a time.
499
+ #
500
+ # When the specifier is an \Integer +index+,
501
+ # returns <tt>self.field(index)</tt>L
502
+ # source = "Name,Name,Name\nFoo,Bar,Baz\n"
503
+ # table = CSV.parse(source, headers: true)
504
+ # row = table[0]
505
+ # row.fields(1) # => ["Bar"]
506
+ #
507
+ # When the specifier is a \Range of \Integers +range+,
508
+ # returns <tt>self.field(range)</tt>:
509
+ # row.fields(1..2) # => ["Bar", "Baz"]
510
+ #
511
+ # When the specifier is a 2-element \Array +array+,
512
+ # returns <tt>self.field(array)</tt>L
513
+ # row.fields('Name', 1) # => ["Foo", "Bar"]
514
+ #
515
+ # When the specifier is a header +header+,
516
+ # returns <tt>self.field(header)</tt>L
517
+ # row.fields('Name') # => ["Foo"]
518
+ #
519
+ # When the specifier is a \Range of headers +range+,
520
+ # forms a new \Range +new_range+ from the indexes of
521
+ # <tt>range.start</tt> and <tt>range.end</tt>,
522
+ # and returns <tt>self.field(new_range)</tt>:
523
+ # source = "Name,NAME,name\nFoo,Bar,Baz\n"
524
+ # table = CSV.parse(source, headers: true)
525
+ # row = table[0]
526
+ # row.fields('Name'..'NAME') # => ["Foo", "Bar"]
441
527
#
528
+ # Returns all fields if no argument given:
529
+ # row.fields # => ["Foo", "Bar", "Baz"]
442
530
def fields ( *headers_and_or_indices )
443
531
if headers_and_or_indices . empty? # return all fields--no arguments
444
532
@row . map ( &:last )
0 commit comments