@@ -726,7 +726,7 @@ def []=(index_or_header, value)
726
726
#
727
727
# ---
728
728
#
729
- # Returns columns data as Arrays,
729
+ # Returns columns data as row Arrays,
730
730
# each consisting of the specified columns data for that row:
731
731
# values = table.values_at('Name')
732
732
# values # => [["foo"], ["bar"], ["baz"]]
@@ -792,11 +792,46 @@ def push(*rows)
792
792
self # for chaining
793
793
end
794
794
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
+ # ---
795
808
#
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.
799
810
#
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"]]
800
835
def delete ( *indexes_or_headers )
801
836
if indexes_or_headers . empty?
802
837
raise ArgumentError , "wrong number of arguments (given 0, expected 1+)"
@@ -821,16 +856,32 @@ def delete(*indexes_or_headers)
821
856
end
822
857
end
823
858
859
+ # Removes rows or columns for which the block returns a truthy value;
860
+ # returns +self+.
824
861
#
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
831
870
#
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
833
880
#
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>
834
885
def delete_if ( &block )
835
886
return enum_for ( __method__ ) { @mode == :row or @mode == :col_or_row ? size : headers . size } unless block_given?
836
887
@@ -848,15 +899,30 @@ def delete_if(&block)
848
899
849
900
include Enumerable
850
901
902
+ # Calls the block with each row or column; returns +self+.
851
903
#
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">
857
914
#
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"]]
859
923
#
924
+ # Returns a new \Enumerator if no block is given:
925
+ # table.each # => #<Enumerator: #<CSV::Table mode:col row_count:4>:each>
860
926
def each ( &block )
861
927
return enum_for ( __method__ ) { @mode == :col ? headers . size : size } unless block_given?
862
928
@@ -869,7 +935,24 @@ def each(&block)
869
935
self # for chaining
870
936
end
871
937
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
873
956
def ==( other )
874
957
return @table == other . table if other . is_a? CSV ::Table
875
958
@table == other
0 commit comments