@@ -726,7 +726,7 @@ def []=(index_or_header, value)
726726 #
727727 # ---
728728 #
729- # Returns columns data as Arrays,
729+ # Returns columns data as row Arrays,
730730 # each consisting of the specified columns data for that row:
731731 # values = table.values_at('Name')
732732 # values # => [["foo"], ["bar"], ["baz"]]
@@ -792,11 +792,46 @@ def push(*rows)
792792 self # for chaining
793793 end
794794
795+ # :call-seq:
796+ # table.delete(*indexes) -> deleted_values
797+ # table.delete(*headers) -> deleted_values
798+ #
799+ # If the access mode is <tt>:row</tt> or <tt>:col_or_row</tt>,
800+ # and each argument is either an \Integer or a \Range,
801+ # returns deleted rows.
802+ # Otherwise, returns deleted columns data.
803+ #
804+ # In either case, the returned values are in the order
805+ # specified by the arguments. Arguments may be repeated.
806+ #
807+ # ---
795808 #
796- # Removes and returns the indicated columns or rows. In the default mixed
797- # mode indices refer to rows and everything else is assumed to be a column
798- # headers. Use by_col!() or by_row!() to force the lookup.
809+ # Returns rows as an \Array of \CSV::Row objects.
799810 #
811+ # One index:
812+ # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
813+ # table = CSV.parse(source, headers: true)
814+ # deleted_values = table.delete(0)
815+ # deleted_values # => [#<CSV::Row "Name":"foo" "Value":"0">]
816+ #
817+ # Two indexes:
818+ # table = CSV.parse(source, headers: true)
819+ # deleted_values = table.delete(2, 0)
820+ # deleted_values # => [#<CSV::Row "Name":"baz" "Value":"2">, #<CSV::Row "Name":"foo" "Value":"0">]
821+ #
822+ # ---
823+ #
824+ # Returns columns data as column Arrays.
825+ #
826+ # One header:
827+ # table = CSV.parse(source, headers: true)
828+ # deleted_values = table.delete('Name')
829+ # deleted_values # => ["foo", "bar", "baz"]
830+ #
831+ # Two headers:
832+ # table = CSV.parse(source, headers: true)
833+ # deleted_values = table.delete('Value', 'Name')
834+ # deleted_values # => [["0", "1", "2"], ["foo", "bar", "baz"]]
800835 def delete ( *indexes_or_headers )
801836 if indexes_or_headers . empty?
802837 raise ArgumentError , "wrong number of arguments (given 0, expected 1+)"
@@ -821,16 +856,32 @@ def delete(*indexes_or_headers)
821856 end
822857 end
823858
859+ # Removes rows or columns for which the block returns a truthy value;
860+ # returns +self+.
824861 #
825- # Removes any column or row for which the block returns +true+. In the
826- # default mixed mode or row mode, iteration is the standard row major
827- # walking of rows. In column mode, iteration will +yield+ two element
828- # tuples containing the column name and an Array of values for that column.
829- #
830- # This method returns the table for chaining.
862+ # Removes rows when the access mode is <tt>:row</tt> or <tt>:col_or_row</tt>;
863+ # calls the block with each \CSV::Row object:
864+ # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
865+ # table = CSV.parse(source, headers: true)
866+ # table.by_row! # => #<CSV::Table mode:row row_count:4>
867+ # table.size # => 3
868+ # table.delete_if {|row| row['Name'].start_with?('b') }
869+ # table.size # => 1
831870 #
832- # If no block is given, an Enumerator is returned.
871+ # Removes columns when the access mode is <tt>:col</tt>;
872+ # calls the block with each column as a 2-element array
873+ # containing the header and an \Array of column fields:
874+ # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
875+ # table = CSV.parse(source, headers: true)
876+ # table.by_col! # => #<CSV::Table mode:col row_count:4>
877+ # table.headers.size # => 2
878+ # table.delete_if {|column_data| column_data[1].include?('2') }
879+ # table.headers.size # => 1
833880 #
881+ # Returns a new \Enumerator if no block is given:
882+ # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
883+ # table = CSV.parse(source, headers: true)
884+ # table.delete_if # => #<Enumerator: #<CSV::Table mode:col_or_row row_count:4>:delete_if>
834885 def delete_if ( &block )
835886 return enum_for ( __method__ ) { @mode == :row or @mode == :col_or_row ? size : headers . size } unless block_given?
836887
@@ -848,15 +899,30 @@ def delete_if(&block)
848899
849900 include Enumerable
850901
902+ # Calls the block with each row or column; returns +self+.
851903 #
852- # In the default mixed mode or row mode, iteration is the standard row major
853- # walking of rows. In column mode, iteration will +yield+ two element
854- # tuples containing the column name and an Array of values for that column.
855- #
856- # This method returns the table for chaining.
904+ # When the access mode is <tt>:row</tt> or <tt>:col_or_row</tt>,
905+ # calls the block with each \CSV::Row object:
906+ # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
907+ # table = CSV.parse(source, headers: true)
908+ # table.by_row! # => #<CSV::Table mode:row row_count:4>
909+ # table.each {|row| p row }
910+ # Output:
911+ # #<CSV::Row "Name":"foo" "Value":"0">
912+ # #<CSV::Row "Name":"bar" "Value":"1">
913+ # #<CSV::Row "Name":"baz" "Value":"2">
857914 #
858- # If no block is given, an Enumerator is returned.
915+ # When the access mode is <tt>:col</tt>,
916+ # calls the block with each column as a 2-element array
917+ # containing the header and an \Array of column fields:
918+ # table.by_col! # => #<CSV::Table mode:col row_count:4>
919+ # table.each {|column_data| p column_data }
920+ # Output:
921+ # ["Name", ["foo", "bar", "baz"]]
922+ # ["Value", ["0", "1", "2"]]
859923 #
924+ # Returns a new \Enumerator if no block is given:
925+ # table.each # => #<Enumerator: #<CSV::Table mode:col row_count:4>:each>
860926 def each ( &block )
861927 return enum_for ( __method__ ) { @mode == :col ? headers . size : size } unless block_given?
862928
@@ -869,7 +935,24 @@ def each(&block)
869935 self # for chaining
870936 end
871937
872- # Returns +true+ if all rows of this table ==() +other+'s rows.
938+ # Returns +true+ if all each row of +self+ <tt>==</tt>
939+ # the corresponding row of +other_table+, otherwise, +false+.
940+ #
941+ # The access mode does no affect the result.
942+ #
943+ # Equal tables:
944+ # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
945+ # table = CSV.parse(source, headers: true)
946+ # other_table = CSV.parse(source, headers: true)
947+ # table == other_table # => true
948+ #
949+ # Different row count:
950+ # other_table.delete(2)
951+ # table == other_table # => false
952+ #
953+ # Different last row:
954+ # other_table << ['bat', 3]
955+ # table == other_table # => false
873956 def ==( other )
874957 return @table == other . table if other . is_a? CSV ::Table
875958 @table == other
0 commit comments