Deleting in a ForEach with .filter

Hi! So the problem that I'm facing is that I'm splitting up a single array into 2 different ones using the .filter method. The problem is that when I try to delete from the "Open lists," it is confused because it deletes from the original, non-split-up eventsList. For example, if I make 3 list items and then mark the 2nd one as complete so it goes into the other list and then try to delete the 2nd one in open (which is actually the 3rd one), it deletes the 2nd one (which is in the completed section). I hope I explained that correctly...

Here is my code for reference..

Code Block {swift}
struct EventsListView: View {
  @EnvironmentObject var viewModel: OlympicGame
   
  @State var showEditEvent: Bool = false
  var body: some View {
    VStack {
      GeometryReader { geometry in
        List {
          HStack {
//other stuff
          }
          Text("Open:").font(.headline)//shadow(radius: 10)
          ForEach(self.viewModel.eventsList.filter { $0.completed == false }) { event in
            NavigationLink(destination: EventInProgressView(event: event)) {
              EventsListItemView(event: event)
              .foregroundColor(Color.black)
                .environmentObject(viewModel)
            }
          }.onDelete(perform: delete)
           
          if self.viewModel.eventsList.filter { $0.completed == true }.count > 0 {
            Text("Completed:").font(.headline)
            ForEach(self.viewModel.eventsList.filter { $0.completed == true }) { event in
              NavigationLink(destination: EventInProgressView(event: event)) {
                EventsListItemView(event: event)
                .foregroundColor(Color.black)
                  .environmentObject(viewModel)
                   
              }
            }
          }
        }
         
      }
    }
    //other stuff was here
  //MARK: Intents
   
  func delete(at offsets: IndexSet) {
    print(offsets)
    viewModel.removeEvent(at: offsets)
  }
}


Here is what my delete looked like in my model:
Code Block {swift}
   mutating func removeEvent(at offsets: IndexSet) {
    eventsList.remove(atOffsets: offsets)
  }


My question is, how do I make it so that when I delete from one ForEach, it actually deletes the one that I tried to delete? Thanks everyone!
hi,

the easiest method (assuming that you only use .onDelete with completed items, where $0.completed == false):
  • since your delete function is given offsets into the "Open" list, start by getting that list with the same filter process, then modify your removal code based on pulling out items from the filtered list by the indices you have. something like this should work:

Code Block
func delete(at offsets: IndexSet) {
let openEvents = viewModel.eventsList.filter { $0.completed == false }
viewModel.removeEvents( offsets.map({ openEvents[$0] }) )
}

where the removeEvents function on your viewModel removes all events in the given list:

Code Block
func removeEvents( events: [Event] ) {
eventList.removeAll(where: { events.contains($0) })
}

of course, you might not actually be removing these; perhaps you are just be setting the completed value to true.

hope that helps,
DMG

Deleting in a ForEach with .filter
 
 
Q