Удаление элементов пользовательских типов данных из массива на основе их атрибутов - PullRequest
0 голосов
/ 23 мая 2019

Я создаю приложение календаря, и одна из функций - позволить пользователю удалять любые предустановленные действия по своему выбору.Мой текущий код получает вводимые пользователем данные за выбранный ими день и отображает все заранее заданные действия в этот день.Затем пользователь вводит имя действия, и код зацикливается, чтобы найти элемент массива с атрибутами типа данных, совпадающими с этим именем действия, и удаляет этот элемент.Код работает до тех пор, пока не существует более одного элемента с тем же днем, что и их атрибут дня, что странно.Может кто-нибудь объяснить мне, почему это так и как мне это исправить?

Я пытался переделать код для использования различных синтаксических функций, таких как отклонение и удаление, но все возвращаются к одной и той же проблеме, которая заключается в том, чтобудет работать, если в один и тот же день нет двух действий, например, если есть два действия с понедельником в качестве пользовательского атрибута дня, ruby ​​скажет, что элемент имеет неопределенный класс

def main
  # code inside my main function to get reminder_list
  puts "Wheeks Calendar App"
  # reads in data from text file and appends to an array
  text_file = File.new("wheeks.txt", "r")
  remind_no = text_file.gets.chomp.to_i
  reminder_list = Array.new
  for x in 0..(remind_no-1)
    reminder = read_reminder(text_file)
    reminder_list << reminder
  end
  text_file.close()
end

def delete_activities reminder_list
  # function to delete elements

  puts ("\n\nYou've chosen to delete activities")
  delete_day = (string_input("Please select a day to delete activities from")).capitalize
  days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
  while !days.include?(delete_day)
    delete_day = (string_input("Please select a proper day")).capitalize
  end 
  puts "Displaying activities from " + delete_day + "\n\n"
  count = 0
  for x in 0..(reminder_list.length-1)
    if (reminder_list[x].day == delete_day)
      puts "Day:" + reminder_list[x].day
      puts "Start time:" + reminder_list[x].startTime.to_s
      puts "End time:" + reminder_list[x].endTime.to_s
      puts "Activity:" + reminder_list[x].activityName
      puts "Comments:" + reminder_list[x].activityComments
      puts "\n"
      count += 1
    end
  end
  if (count == 0)
    puts "There are no activities on that day\n\n"
  else
    delete_activity = (string_input("From the activities displayed, input the activity name of the activity you want to delete")).downcase
    for x in 0..(reminder_list.length-1)
      if (reminder_list[x].day == delete_day)
        if (reminder_list[x].activityName == delete_activity)
          reminder_list.delete_at(x)
          puts "Activity " + delete_activity + " has been deleted from " + delete_day + "\n\n"
        end 
      end
    end
  end
end

1 Ответ

0 голосов
/ 23 мая 2019

Проблема, которую я вижу, состоит в том, что вы циклически просматриваете индексы, удаляя элементы из массива.Это вызывает смещение элементов массива при удалении первого элемента, что, в свою очередь, заставляет цикл пропустить один элемент после удаления одного из элементов.

Я рекомендую использовать #reject!:

delete_activity = string_input("From the activities displayed, input the activity name of the activity you want to delete").downcase

reminder_list.reject! do |activity|
  to_delete = activity.day == delete_day && activity.activityName == delete_activity

  if to_delete
    puts "Activity #{delete_activity} has been deleted from #{delete_day}\n\n"
  end

  to_delete
end

Или, если не возражаете, пропустить вызов puts.

reminder_list.reject! do |activity|
  activity.day == delete_day && activity.activityName == delete_activity
end
...