Remove Object From Array with Specific Requirement - arrays

I have a custom object Shift
struct Shift: Identifiable, Encodable, Equatable {
var id: String = UUID().uuidString
var weekday: String
var startTime: Date
var endTime: Date
}
And an array of Shift objects:
#Published var shifts: [Shift] = []
I would like to remove the last item in the array where the value of weekday is equal to "Monday"
I tried this but it throws an error saying Value of type 'Array<Shift>.Index' (aka 'Int') has no member 'removeLast'
if let index = shifts.firstIndex(where: {$0.weekday == "Monday"}) {
index.removeLast()
}
Any help is appreciated :)

No, you want the last index and you want to remove the item from the shifts array rather than from the index
if let index = shifts.lastIndex(where: {$0.weekday == "Monday"}) {
shifts.remove(at: index)
}

Related

How to append an array inside an array?

I have an array of working hours, and within that array, there is another array of shifts. I would like to remove all instances in the shifts array where weekday is equal to "Monday"
struct Shift {
let id: String = UUID().uuidString
var weekday: String
var startTime: String
var endTime: String
var error: Bool
}
struct WorkingHours: Identifiable {
let id: String = UUID().uuidString
var availability: [Shift]
}
class AvailabilityManager: ObservableObject {
#Published var workingHours: [WorkingHours] = []
}
In my view:
#EnvironmentObject var availabilityManager: AvailabilityManager
self.availabilityManager.workingHours.removeAll(where: {$0.availability.weekday == "Monday"})
However, it says: "Value of type '[Shift]' has no member 'weekday'"
Any help is appreciated :)
Change
self.availabilityManager.workingHours.removeAll(where: {$0.availability.weekday == "Monday"})
To
self.availabilityManager.workingHours.removeAll(where: {$0.availability.contains(where: {$0.weekday == "Monday"})})
More shorthand method
self.availabilityManager.workingHours.removeAll { $0.availability.contains { $0.weekday == "Monday" } }
Add the following function to WorkingHours
mutating func removeShift(weekDay: String) {
availability = availability.filter { $0.weekday != weekDay }
}
and call it like
workingHour.removeShift(weekDay: "Monday")
If you have an array of WorkinHours you can call the method using map for instance
workingHoursArray = workingHoursArray.map {
var workingHours = $0
workingHours.removeShift(weekDay: "Monday")
return workingHours
}

No exact matches in call to instance method 'append' in swift

Tried to combine or merging two model to one model
1st model = items [ InboxModel]. (My own Inbox)
2nd model = items2 [MoInboxModel] (SDK Inbox)
1st + 2nd -> combinedItems
private var items: [InboxModel] = []
private var items2: [MoInboxModel] = []
private var combinedItems: [combinedInboxModel] = []
struct InboxModel {
let id: String
let title: String
let message: String
let date: Date
}
struct MoInboxModel {
let id: String
let title: String
let message: String
let date: Date
}
struct combinedInboxModel {
let id: String
let title: String
let message: String
let date: Date
}
self?.combinedItems.append(self?.items). //No exact matches in call to instance method 'append
self?.combinedItems.append(contentsOf: self?.items2 ?? []) //No exact matches in call to instance method 'append
Why there is an error while merge it ? How to merge it correctly?
You have three unrelated types - InboxModel, MoInboxModel and combinedInboxModel (Which should be CombinedInboxModel. Even though they all have properties with the same name, they are different types.
There is no append function on an array of combinedInboxModel that accepts an array of InboxModel or MoInboxModel.
You could use map on each of your two input arrays to convert them to an array of CombinedInboxModel which you can then put into combinedItems.
Presumably you are writing this code in a closure, which is why you have a weak self. Best to deal with that first and then process your arrays.
guard let self = self else {
return
}
self.combinedItems = self.items.map { CombinedInboxModel(id:$0.id,title:$0.title,message:$0.message,date:$0.date) }
let items2 = self.items2.map { CombinedInboxModel(id:$0.id,title:$0.title,message:$0.message,date:$0.date) }
self.combinedItems.append(contentsOf:items2)
You haven't shown where items and items2 come from; Is it possible just to fetch them as instances of the same struct to start with?
The fact that you have three structs with the same properties is a bit fishy. I would consider a different design if I were you.
However, if you must go with this approach, you might want to consider starting with a protocol and getting rid of the combinedInboxModel struct.
protocol InboxModelable {
var id: String { get }
var title: String { get }
var message: String { get }
var date: Date { get }
}
Now make your two structs conform to InboxModelable.
struct InboxModel: InboxModelable {
let id: String
let title: String
let message: String
let date: Date
}
struct MoInboxModel: InboxModelable {
let id: String
let title: String
let message: String
let date: Date
}
Since both of your types conform to InboxModelable you can directly store both types in an array of type Array<InboxModelable> without having to map the elements.
class SomeClass {
private var items: [InboxModel] = []
private var items2: [MoInboxModel] = []
private var combinedItems: [InboxModelable] = []
func combineItems() {
doSomething { [weak self] in
guard let self = self else { return }
self.combinedItems.append(contentsOf: self.items)
self.combinedItems.append(contentsOf: self.items2)
}
}
}

How to get firstindex of array in struct Swift

Hi I have a struct like this
struct OrderCaches: Codable {
var food, drink: [Food]?
}
struct Food: Codable{
var id: Int?
var name: String?
var quantity: Double?
var notes: String?
}
I want to get first index where id = productList[indexPath.row].id
I tried with:
let index = OrderCaches.firstIndex(where: {$0.food.id == productList[indexPath.row].id})
but not work I get this error "Value of type '[Food]?' has no member 'id'".
How can I get the first Index?
Thanks
The function firstIndex is not a static member, but an instance member, hence you have to create an instance of OrderCache to get the index, like below:
let orderCaches = OrderCaches(food: [], drink: [])
let index = orderCaches.food?.firstIndex(where: { $0.id == productList[indexPath.row].id })

Append array value to struct

I have following struct:
struct PalletScan: Codable {
var deliveryId: String?
var userId: String?
var timestamp: String?
var tempPalletNr: String?
var tempLocation: String?
var tempPalletType: String?
var pallets: [MovementScan]?
//coding keys requried for translation API -> struct -> CoreData and CoreData -> struct -> API
enum CodingKeys: String, CodingKey {
case deliveryId = "TOID"
case userId = "UserId"
case timestamp = "TimeStamp"
}
mutating func appendMovementScan() {
var movementScan = MovementScan()
movementScan.locationId = self.tempLocation
movementScan.palletId = self.tempPalletNr
movementScan.palletType = self.tempPalletType
movementScan.timestamp = String(Date().timeIntervalSince1970)
print(movementScan)
self.pallets?.append(movementScan)
}
}
however self.pallets?.append(movementScan) does not adding anything to the pallets array. What am I missing? It must be trivial but can not find mistake.
Just change var pallets: [MovementScan]?
to
var pallets: [MovementScan] = [MovementScan]()
as #Carcigenicate you call append on nil value
var pallet is not initialized and it is an optional so when you append movementscan using ? , it wont be executed.
To fix this you have to some how initialize pallets array before appending to it .
One way can be simply initialize with empty array :
var pallets = [MovementScan]()

Swift Array remove only one item with a specific value

Alright, this should not be too difficult, but Sunday morning proves me wrong...
I have an Array with structs, and want to remove only one struct that matches its name property to a String. For example:
struct Person {
let name: String
}
var myPersons =
[Person(name: "Jim"),
Person(name: "Bob"),
Person(name: "Julie"),
Person(name: "Bob")]
func removePersonsWith(name: String) {
myPersons = myPersons.filter { $0.name != name }
}
removePersonsWith(name: "Bob")
print(myPersons)
results in:
[Person(name: "Jim"), Person(name: "Julie")]
But how do I only remove one Bob?
filter filters all items which match the condition.
firstIndex returns the index of the first item which matches the condition.
func removePersonsWith(name: String) {
if let index = myPersons.firstIndex(where: {$0.name == name}) {
myPersons.remove(at: index)
}
}
However the name of the function is misleading. It's supposed to be removeAPersonWith ;-)

Resources