Removing Specific Object In Array Based On Property? - ios

I have an array of drink toppings and want to remove the ones that aren't relevant to the drink, this is the code I have, but I can't figure out how to remove the topping from the array if it isn't within the criteria.
I can only remove at index path and this can change if we added more toppings etc so didn't seem accurate?
for toppings in self.toppings {
if self.selectedDrink.name == "Tea" {
if toppings.limit == "C" {
self.toppings.remove(at: toppings)
}
}
}
Essentially if the user selected Tea it looks for toppings limited for coffee and then I need to remove those ones that respond to the "C" property, but I can't see how?
Thanks for the help!

You can do in-place removal with a for loop, but it would be tricky, because you would need to iterate back to avoid disturbing indexes.
A simpler approach is to filter the array, and assign it back to the toppings property, like this:
toppings = toppings.filter {$0.limit != "C"}

Related

Storing data on Filter Selections

My doubt is regarding Filter Screen.
I want to store & remove data which user selected & deselected from Filter Screen respectively. I am not sure what data type to use here.
As it appears from below image :
Suppose I have Few filter headings like "Category", "Color", "Unit",etc.
& inside of every heading i have some values like in category I have values from category 1, category 2... upto category 50.
Now when user selects anything like Category2, category3.. I can store those particular values in Array, but when user deselect any category(unchecking the checkboxes) randomly then how i will be able to remove that particular value from array because i can't get related index inside array.(means like user selected some 10 categories then i have some 10 values inside my array but thay are not matched indexwise with values from tableView index.)
Assist me on how to approach this..
Here is how i would approach the problem. Assuming i have a data source which would contain the items without applying any filter. (In practice this is not how it would be, you would probably be getting your data source via network calls) Once a user applies or removes a filter by checking or unchecking the checkbox, i would filter the data source with the active filters.
Let's say this is your item class.
class Item {
var category: Category
var color: Color
}
enum Category {
case one
case two
.
.
case none
}
// Similarly for color and other parameters
Now this would be your filter object that maintains all the filters that are active.
class FilterParameters {
var category: [Category]? = nil
var color: [Color]? = nil
}
Create an object of this class and every time a filter is checked or unchecked, filter your data source with the current active filters. (If a filter is not selected then ignore that filter and construct filter parameters based on the ones you do have).

How to sort array based on key?

I have an array which has two types of objects: Awarded and non-awarded. I simply want to sort my array so that awarded objects are placed first, and the rest are placed afterwards.
Here is the code that defines the key "awarded":
if let awarded = achievements[indexPath.row].userRelation["awarded"] as? String where awarded != "<null>" { }
Within those brackets I'd like to use my unwrapped value "awarded" to sort through the achievements and add those to the beginning, and the rest at the end.
How would I go about doing that?
You should experiment with sort function, it is very useful.
let sortedAchievements = achievements.sorted{ $0.userRelation["awarded"] < $1.userRelation["awarded"] }
To sort in place use this:
achievements.sort{ $0.userRelation["awarded"] < $1.userRelation["awarded"] }
I would recommend to refactor your model. It's better to use objects or structs instead of dictionaries. Also awarded should be a Bool property, not a String, right?

UITableViewController Sections

I'm trying to recreate the buggy CNContactPickerViewController made by Apple so I have an array of data [CNContact] which i need to display neatly in a UITableView. It all works great until i try to add sections based on the first letter of the contacts' last names to that table. The only solution i found is to iterate through the [CNContact] array and manually group every contact into a dictionary, based on their initials resulting in a [String:[CNContact]]. Is there a better way to do this?
The end result can be viewed in the screenshot below.
This will sort your contacts by last name. Might be overkill, as you want them grouped only by the first letter of the last name, whereas this will sort using the whole name.
var contacts :[CNContact] = [CNContact]();
// fill your contacts here
contacts.sortInPlace { (contact1, contact2) -> Bool in
contact1.familyName.compare(contact2.familyName) == .OrderedAscending
}
Not sure if you need the original ordering. If you want the original array, do create copy of the old one, and do sort in place for the copy.

Lua 5.0 - iterations over tables ignore duplicate keys even though values are different

Reading the injected comments in the Code Snippet should give enough context.
--| Table |--
QuestData = {
["QuestName"]={
["Quest Descrip"]={8,1686192712},
["Quest Descrip"]={32,1686193248},
["Quest Descrip"]={0,2965579272},
},
}
--| Code Snippet |--
--| gets QuestName then does below |--
if QuestName then
-- (K = QuestName) and (V = the 3 entries below it in the table)
for k,v in pairs(QuestData) do
-- Checks to make sure the external function that obtained the QuestName matches what is in the table before cont
if strlower(k) == strlower(QuestName) then
local index = 0
-- Iterates over the first two pairs - Quest Descrip key and values
for kk,vv in pairs(v) do
index = index + 1
end
-- Iterates over the second two pairs of values
if index == 1 then
for kk,vv in pairs(v) do
-- Sends the 10 digit hash number to the function
Quest:Function(vv[2])
end
end
end
end
end
The issue I'm running into is that Lua will only pick up one of the numbers and ignore the rest. I need all the possible hash numbers regardless of duplicates. The QuestData table ("database") has well over 10,000 entries. I'm not going to go through all of them and remove the duplicates. Besides, the duplicates are there because the same quest can be picked up in more than one location in the game. It's not a duplicate quest but it has a different hash number.
Key is always unique. It is the point of the key, that the key is pointing to unique value and you can't have more keys with same name to point different values. It is by definition by Lua tables.
It is like if you would want to have two variables with same name and different content. It does not make sense ...
The table type implements associative arrays. [...]
Like global variables, table fields evaluate to nil if they are not initialized. Also like global variables, you can assign nil to a table field to delete it. That is not a coincidence: Lua stores global variables in ordinary tables.
Quote from Lua Tables
Hashing in Lua
Based on comments, I update the answer to give some idea about hashing.
You are using hashing usually in low-level languages like C. In Lua, the associative arrays are already hashed somehow in the background, so it will be overkill (especially using SHA or so).
Instead of linked lists commonly used in C, you should just construct more levels of tables to handle collisions (there is nothing "better" in Lua).
And if you want to have it fancy set up some metatables to make it somehow transparent. But from your question, it is really not clear how your data look like and what you really want.
Basically you don't need more than this:
QuestData = {
["QuestName"]={
["Quest Descrip"]={
{8,1686192712},
{32,1686193248},
{0,2965579272},
},
},
}
As Jakuje already mentioned table keys are unique.
But you can store both as a table member like:
QuestData = {
-- "QuestName" must be unique! Of course you can put it into a table member as well
["QuestName"]={
{hash = "Quest Descrip", values = {8,1686192712} },
{hash = "Quest Descrip", values = {32,1686193248} },
{hash = "Quest Descrip", values = {0,2965579272} }
}
}
I'm sure you can organize this in a better way. It looks like a rather confusing concept to me.
You've said you can't "rewrite the database", but the problem is the QuestData table doesn't hold what you think it holds.
Here's your table:
QuestData = {
["QuestName"]={
["Quest Descrip"]={8,1686192712},
["Quest Descrip"]={32,1686193248},
["Quest Descrip"]={0,2965579272},
},
}
But, this is actually like writing...
QuestData["Quest Descrip"] = {8,1686192712}
QuestData["Quest Descrip"] = {32,1686193248}
QuestData["Quest Descrip"] = {0,2965579272}
So the second (and then, third) values overwrite the first. The problem is not that you can't access the table, but that the table doesn't contain the values any more.
You need to find a different way of representing your data.

swift - display items in table view by category / tag?

Im building a swift app and need some help with two problems. I'm fairly new to swift and coding in general. My app saves a bunch of items into an array, and currently the tableview on the home screen displays them. but i'd like to take it a step further and would like to be able to categorize the items. for example, a shopping list. You could save "bananas", "pasta", "apples", "bread", "strawberries", and "Milk" as items into the array.
How could I associate a tag to each item? Say, tag bananas, apples, and strawberries as "fruit" and save that item to the array.
and
How could I display just items with the "fruit" tag in a tableview? Lets say the home screen is a list of all items, but you select the tag, and it then just displays items with the "fruit" tag...etc.
this is just a simple example to help illustrate my point, but I'd like to know how to work with my data like this.
If anyone has any ideas or any resources to point me in the right direction, I'd really appreciate it.
Thanks!
To associate some things with another in Swift (and in almost all programming languages) you should use Dictionaries. How to implement it in your case? Well, very simple. First, i suggest you to create enum to store you food types or whatever:
enum FoodType {
case Fruits, Vegetables
}
Now, create your food repository, where you store food (or value) and associate its with some tag (or key):
var myFood = [FoodType : [String]]()
Now you can add you food to your myFood variable like this:
food[.Fruits] = ["Bananas", "Apples", "Strawberries"]
food[.Vegetables] = ["Potato", "Carrot"]
To select fruits do this:
var onlyFruits = food[.Fruits]
Now, onlyFruits contains only food that tagged by .Fruits.

Resources