How do I calculate the items in a class' property? Swift language - ios

A method should calculate the price of all the items in a class’s property. Unfortunately, my knowledge when it comes to programming is ultra limited. Any help would be very much appreciated.
Thanks in advance.

In Swift3
using reduce
func priceBeforeDiscounts() -> Int {
return items.reduce(0) { (result, item) in
return result + item.priceInPence
}
}
using for in loop
func priceBeforeDiscounts() -> Int {
var sum: Int = 0
for item in items {
sum += item.priceInPence
}
return sum
}

Here you have some useful code (prepared in playground) for you:
// This is your item class
class Item {
var priceInPence: Int = 0
init(price: Int) {
priceInPence = price
}
}
// This is your array of items
var items = [Item]()
// Here I create items with given price
for _ in 0...3 {
items.append(Item(price: 2))
}
// This is the most interesting part for you, here you sum up prices from items in array
let sum = items.reduce(0, { $0 + $1.priceInPence })
print(sum)
I created this code in playground, so you can copy/past this code to your playground and play with it. Having my example you should be able to update your source code.

Related

Swift Realm - How to COUNT all data from single column?

Here is what my class looks like:
class Card : Object {
#objc dynamic var tags: String = ""
#objc dynamic var set_id: String = ""
}
I want to return number of tags from all Cards with forwarded set_id.
Here is the method:
func totalTags() -> String {
var tagCounter: Int = 0
let realm = try? Realm()
let totalCards = realm!.objects(Card.self).filter("set_id = '\(setId)'") //all Cards with selected set_id, set_id is global var.
for card in 0...totalCards.count {
//every 'card' has tags, but there there can me more tags,
//like : tags="one,twitter,world,Europe"...
//And I want to count all of them for every 'card'
let result = realm.objects(Card.self).filter() //How to filter?
tagCounter += //what? result.count or something?
}
return String(tagCounter)
}
I understand that tags: String contains comma separated elements and you want to find the number of elements.
You can do that by iterating over totalCards. For each card, split the tags into an array and count the number of elements.
for card in totalCards {
tagCounter += card.tags.components(separatedBy: ",").count
}
components(separatedBy:) documentation
I know this was already answered but I just want to share how to do it my own way.
let tagsCount = totalCards.map { $0.tags.components(separatedBy: ",") }.flatMap { $0 }.filter { !$0.isEmpty }.reduce(into: 0, { result, _ in
result += 1
})
Thanks. Happy coding :)

How to query List<Int> on Realm Swift

How can I filter out the RealmFilter.objectIds that has a given Int?
func delete(ids: [Int]) {
let filterResultsToDelete = realm.objects(CRMRealmFilterResult.self).filter("ANY objectIds IN %#",ids)
//Crashes
}
class RealmFilterResult : Object {
#objc dynamic var filterId: Int = 0
let objectIds = List<Int>()
override static func primaryKey() -> String {
return "filterId"
}
}
This may not be at all what you want but it was a good exercise. Maybe this will help.
Let me re-state what I think you're asking: You've got a series of objects that each have a List property of Int's and you want to be able to query for all objects that have a particular int in their list
Using a more real-world example, suppose we have a list of teams and we keep a list of game scores (a list) within each team
class TeamObject: Object {
#objc dynamic var object_id = NSUUID().uuidString
let scoreList = List<ScoreObject>()
override static func primaryKey() -> String? {
return "object_id"
}
}
and we have a score object that stores a score as an Int (and maybe other details like who they played or the date)
class ScoreObject: Object {
#objc dynamic var score = 0
let teamsWithScores = LinkingObjects(fromType: TeamObject.self, property: "scoreList")
}
For simplicity, let's create three scores and two teams and give each team two scores in their list.
let score1 = ScoreObject()
score1.score = 1
let score2 = ScoreObject()
score2.score = 2
let score3 = ScoreObject()
score3.score = 3
let t1 = TeamObject()
t1.scoreList.append(score1)
t1.scoreList.append(score3)
let t2 = TeamObject()
t2.scoreList.append(score2)
t2.scoreList.append(score3)
and write them to realm
try! realm.write {
realm.add(t1)
realm.add(t2)
}
from there, we can get any team that has a score of 1, which solves the question of getting the objects that have a list that contain a given int.
let results = realm.objects(ScoreObject.self).filter("score IN %#", [1])
if results.count > 0 {
for aScore in results {
let teamsWithThisScore = aScore.teamsWithScores
for team in teamsWithThisScore {
print("score: \(aScore.score)")
print(" id: \(team.object_id)")
}
}
} else {
print("no teams with those scores")
}
you can expand on this to get teams (object) that have several scores (ints)
let results = realm.objects(ScoreObject.self).filter("score IN %#", [1,3])
As I said, it may be off base but it does provide a solution in a more object oriented way.
Querying List of primitives (i.e. non Object subclasses, like Int in your case) is not yet supported by Realm.
You can follow the status of this on this GitHub issue.

How can I filter a single category in UICollectionView in swift?

I'm new in swift and I have some problem while I try to filter some categories in my UICollectionView.
Here my code to get all articles for all the categories.
func getArticlesforCategory(category: String) -> Int {
var result : Int = 0
for article in self.allArticles {
if category == article.category {
result += 1
}
}
return result
}
How can I filter only one single category, for example "test"?
I get all the categories by parsing xml from wordpress website
You can use filter function to filter your array :
func getArticlesforCategory(category: String) -> Int {
let filteredArray = allArticles.filter( {$0.category == category }) // Here you have filtered array
return filteredArray.count // If you want number of items pass count of filtered array
}
try below line:
let result = self.allArticles.filter { $0.category == "test" }.count
You can use filter, try this code
func getFilteredArray(category: String) -> [ array of your objects] {
let filteredArray = allArticles.filter( {$0.category == category })
return filteredArray
}

How do you store integer values in a SKLabelNode

I am trying to store in integer value in a SKLabelNode but I keep geting an error that I can only store strings. I need it as an integer later. Here is my code:
import SpriteKit
import GameplayKit
class GameScene: SKScene {
override func didMove(to view: SKView) {
var comScore = SKLabelNode()
comScore.fontName = "Pong Score"
comScore.text = 0
comScore.fontSize = 100
comScore.color = SKColor.white
comScore.position = CGPoint(x: 200, y: 220)
comScore.zPosition = 3
addChild(comScore)
}
}
Help would be greatly appreciated as I am new to SpriteKit.
An SKLabelNode's text property is a string, not an Int. You can make it a string by adding quotes:
comScore.text = "0"
or you can convert a Int variable to a string:
comScore.text = String(myIntValue)
I fixed this issue by storing it as a String initaly and then using the following code converted it back and forth:
var comScoreInt: Int = Int(comScore.text!)!
comScoreInt += 1
comScore.text = String(comScoreInt)
In addition to the other answers regarding Ints and Strings, if you stick a property watcher on your score, you can get the label updated automatically when you update the score:
var comScoreInt: Int {
didSet{
comScore.text = String(comScoreInt)
}
}
Edit:
If, as per your own answer, you want to initialise the score from the value in the score label, then make the integer score a computed property:
var comScoreInt -> Int {
get {
return Int(comScore.text!)
}
set(newScore) {
comScore.text = String(newScore)
}
}
Now you can retrieve comScoreInt and it will return the value in the score label and set comScoreInt and it will update the label.
Swift 3
Extensions are your friend:
extension String {
func integerValue() > Int? {
return Int(trimmingCharacters(.whitespacesAndNewlines))
}
static func + (left: String, right: Int) -> String {
guard let value = left.integerValue() else {return left}
return "\(value + right)"
}
static func += (inout left: String, right: Int) {
left = left + right
}
}
Now you can quickly add to a String doing label.text += 1
You end up losing some protections doing it this way though, since you would normally expect String + Int to throw you an error, so you may want to think about the security of this process, and perhaps either subclass String to NumberString so that only a certain type of string can be added with an Int,
or add some error handling into the extensions provided.
You can even take this one step further, and parse out the Int from a String (e.g. "Points: 1") and change the value.
This answer should not be seen as the definitive answer to use for your problem, I am basically offering a basic building block alternative that you may want to consider in your development.

How to I look through an array that exists in a dictionary in Swift?

I am trying to loop through array that exists in a dictionary.
What am I doing wrong and how should this work?
public func getItemCount() -> Int{
var count = 0
for item in order.object(forKey:"items") as? Array {
count += 1
//other instructions
}
return count
}
Try breaking it down to two steps.
public func getItemCount() -> Int{
if let thisArray:[AnyObject] = order.object(forKey:"items") as? [AnyObject] {
for item in thisArray {
}
}
}
Feel free to suggest edits. Please let me know if it doesn't work

Resources