user6398538
user6398538

Reputation:

Delete an array from a class in ruby

So I am creating a class in ruby where in I will be able to insert my data on a text file and then read, find from it but I am stuck on delete as well update/edit.

Basically I created a method called "find" and I made it as a reference on my "delete" method.

def find(keyword="")
  if keyword
    person = People.read_people
    found = person.select do |pip|
      pip.name.downcase.include?(keyword.downcase) ||
        pip.age.downcase.include?(keyword.downcase) ||
        pip.country.downcase.include?(keyword.downcase)
    end
    found.each do |person|
      puts person.name + " | " + person.age + " | " + person.country
    end
  else
    puts "find using a key phrase eg. 'find sam' \n\n"
  end
end


def list
  puts "\nListing People \n\n".upcase
  people = People.read_people
  people.each do |person|
    puts person.name + " | " + person.age + " | " + person.country
  end
end


def delete(keyword="")
  if keyword
    person = People.read_people
    found = person.select do |pip|
      pip.name.downcase.include?(keyword.downcase) ||
        pip.age.downcase.include?(keyword.downcase) ||
        pip.country.downcase.include?(keyword.downcase)
    end
    person.delete(found)
  else
    puts "find using a key phrase eg. 'find josh' \n\n"
  end
end

As you can see I was trying to delete the supplied keyword from the array (w/c was save on a text file) via class method called read_people. Here's how it looks like:

def self.read_people
  # read the people file
  # return instances of people
  people = []
  if file_usable?
    file = File.new(@@filepath, 'r')
    file.each_line do |line|
      people << People.new.import_line(line.chomp)
    end
    file.close
  end
  return people
end

def import_line(line)
  line_array = line.split("\t")
  @name, @age, @country = line_array
  return self
end

How can I fix this and delete the found item via keyword?

See the actual codes here: https://repl.it/repls/VastWildFact

Upvotes: 0

Views: 67

Answers (2)

Gavin Miller
Gavin Miller

Reputation: 43825

Basically you're going to want an export_people and write_people method that'll look something like this:

def self.export_people(people)
  people.map do |person|
    [person.name, person.age, person.country].join("\t")
  end
end

def self.write_people(people)
  File.new(@@filepath, 'w') do |f|
    f.write(export_people(people))
  end
end

# Usage:
Person.write_people(array_of_people)

With the above code, you'd call the modified delete method as detailed in Tarek's answer, and then Person.write_people(array_of_people) to write back to the file.

Upvotes: 1

Tarek N. Elsamni
Tarek N. Elsamni

Reputation: 1837

Change

person.delete(found)

to

person -= found # Equivalent to person = person - found

It should work as per https://ruby-doc.org/core-2.2.0/Array.html#method-i-2D

ary - other_ary → new_ary

Returns a new array that is a copy of the original array, removing any items that also appear in other_ary. The order is preserved from the original array.

It compares elements using their hash and eql? methods for efficiency.

Example: [ 1, 1, 2, 2, 3, 3, 4, 5 ] - [ 1, 2, 4 ] #=> [ 3, 3, 5 ]


Another solution is to use reject as follows:

person.reject! do |pip|
  pip.name.downcase.include?(keyword.downcase) ||
    pip.age.downcase.include?(keyword.downcase) ||
    pip.country.downcase.include?(keyword.downcase)
end

Upvotes: 1

Related Questions