2

I have two array of objects that look like this:

MeetingRoomSuggestions:

init(suggestionReason: String, organizerAvailability: String,
startTime: String, endTime: String, dStart: Date, availability: String,
emailAddress: String, displayName: String, roomEmail: String,
occupancy: Int, building: String)

and Bookings:

init(startTime: String, endTime: String, dStart: Date, organizer :
String, location : String, subject : String)

I want to be able to filter / exclude MeetingRoomSuggestion objects from my array if the dStart property exists in the Bookings array.

My Code:

  let filteredArr = meetingRoomSuggestions.filter { meeting in
        return bookingArray!.contains(where: { booking in
            return booking.dStart == meeting.dStart
        })
    }

I also tried filtering on the start string - which is the same in both. When I print out both the arrays before filtering - you can clearly see there is a booking that exists with the same dStart. How can I exclude this?

After filtering and printing out using the code:

print("meetings:")
        for meeting in self.meetingRoomSuggestions {
            print(meeting.roomEmail)
            print(meeting.dStart)
            print(meeting.startTime)
        }
        print()
        print("bookings:")
        for booking in self.bookingArray! {
            print(booking.location)
            print(booking.dStart!)
            print(booking.start)
        }            

        print("filtered array: ", filteredArr)

        for items in filteredArr {
            print("email: ", items.roomEmail)
            print("dstart: ", items.dStart)
        }

Returns:

    meetings:
FirstFloorTestMeetingRoom1@qubbook.onmicrosoft.com
2019-02-20 15:00:00 +0000
2019-02-20T15:00:00.0000000
GroundFloorTestMeetingRoom1@qubbook.onmicrosoft.com
2019-02-20 15:00:00 +0000
2019-02-20T15:00:00.0000000

bookings:
FirstFloorTestMeetingRoom1@qubbook.onmicrosoft.com
2019-02-20 15:00:00 +0000
2019-02-20T15:00:00.0000000
gfprojectroom1@qubbook.onmicrosoft.com
2019-02-21 10:00:00 +0000
2019-02-21T10:00:00.0000000
gfprojectroom1@qubbook.onmicrosoft.com
2019-02-21 16:00:00 +0000
2019-02-21T16:00:00.0000000

filtered array:  [QUBook.MeetingSuggestion, QUBook.MeetingSuggestion]
email:  FirstFloorTestMeetingRoom1@qubbook.onmicrosoft.com
dstart:  2019-02-20 15:00:00 +0000
email:  GroundFloorTestMeetingRoom1@qubbook.onmicrosoft.com
dstart:  2019-02-20 15:00:00 +0000

For some reason, the filtered array is the same as the original meetingRoomSuggestions array - it doesn't filter out the occurrence of an object with the same dStart. I suspect the filter is wrong? I have previously been able to filter array of objects by comparing them with array of strings etc but not like this.

Liam
  • 55
  • 7

1 Answers1

6

You are using some kind of reverse logic here. What you should be doing is this:

let filteredArr = meetingRoomSuggestions.filter { meeting in
    return !bookingArray.contains(where: { booking in
        return booking.dStart == meeting.dStart
    })
}

In plain english: filter meetings, leaving those that do not have their dStart values equal to the dStart value of any object in the bookingArray.

pckill
  • 3,709
  • 36
  • 48
  • edited my answer. I tried this way of filtering firstly and it wouldn't filter out the meeting I wanted.. Does not pick up / filter even though there is a booking with the same dStart? ^ See prints above – Liam Feb 20 '19 at 15:15
  • 1
    @Liam, I think you forgot the `!`, as in `!bookingArray.contains` – pckill Feb 20 '19 at 15:19
  • @LeoDabus, well, I do not think so. At least not when explaining something to someone. – pckill Feb 20 '19 at 20:32
  • @LeoDabus, no, I would not. This is not a place where it would be elegant, which kinda defeats the only purpose implicit returns have. – pckill Feb 20 '19 at 20:57
  • how would I alter this filter statement to filter out any meeting suggestions that have a start time that is before the ending of any other booking? e.g. booking.dStart == meeting.dStart or booking.dStart + booking.duration >= meeting.dStart? – Liam Feb 20 '19 at 21:59
  • @Liam, yep, something like that. See https://stackoverflow.com/questions/39018335/swift-3-comparing-date-objects – pckill Feb 20 '19 at 22:22
  • can you look at my edit please - would I have to change the filter to this to resolve? return (booking.dStart == meeting.dStart) && (booking.roomEmail == meeting.roomEmail) – Liam Feb 20 '19 at 22:36
  • 1
    @Liam, sure, feel free to adjust the filter logic according to your requirements – pckill Feb 21 '19 at 08:42