Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the ability to delete multiple columns #4

Merged
merged 2 commits into from
Feb 5, 2018
Merged

Conversation

wowinter13
Copy link
Contributor

When I was working with some statistics using Ruby/csv, I discovered that the mechanism for deleting columns is very peculiar in Ruby and we can't easily just delete more than 1 column.
We can do it like this (DRY):

csv_table.delete("PassengerId")
csv_table.delete("Survived")
csv_table.delete("Name")
csv_table.to_csv

Or like this (will destroy csv structure -> Array of Arrays):

datus = CSV.readlines('titanic.csv', headers:true).map{|row| row.values_at('PassengerId','SibSp') }

And finally the best working way for me:

to_del = ["Name", "Ticket"]
csv_table = datus.by_col!.delete_if { |name, values| !to_del.include? name}

But I think it should work easily like this:

to_del = ["Name", "Ticket"]
data.delete(to_del)

So I rewrote method a little and added this functionality. If you have any ideas: create another delete_columns method or maybe better ways to fast delete columns, I will be glad to hear it:)

lib/csv.rb Outdated
@@ -807,15 +807,19 @@ def push(*rows)
end

#
# Removes and returns the indicated column or row. In the default mixed
# Removes and returns the indicated columns or row. In the default mixed
# mode indices refer to rows and everything else is assumed to be a column
# header. Use by_col!() or by_row!() to force the lookup.
#
def delete(index_or_header)
Copy link
Member

@kou kou Feb 3, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*indexes_or_headeres is better than accepting an Array argument.

lib/csv.rb Outdated
# mode indices refer to rows and everything else is assumed to be a column
# header. Use by_col!() or by_row!() to force the lookup.
#
def delete(index_or_header)
if @mode == :row or # by index
if index_or_header.is_a? Array # by array of headers
index_or_header.each do |element|
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method should return the deleted objects.

indexes_or_headers.map do |index_or_header|
  delete(index_or_header)
end

@wowinter13
Copy link
Contributor Author

@kou Thanks for review and I changed checked methods. Can you view current version please?

@kou kou merged commit 72d811b into ruby:master Feb 5, 2018
@kou
Copy link
Member

kou commented Feb 5, 2018

Thanks.
I've merged and reverted zero argument (raising ArgumentError) and one argument (returning without wrapping by an Array) case behavior for backward compatibility.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants