0

I am working on the project where I have an array for class objects. I want to iterate each object and see if there exist duplicate values in the array then add or sum values into one.

Example:

class SomeClass: NSObject {

internal var displays: Int?
internal var id: String?
}

I have an array of SomeClass, when id is the same then add values of displays into one.

Thanks

3
  • 2
    Show what you tried and explain what went wrong Commented Sep 19, 2016 at 6:36
  • Have a look at NSCountedSet Commented Sep 19, 2016 at 6:47
  • I was trying with For loop but it i didn't work out. I am trying with Map, Filter and reduce but so far it didn't work out as well. I spent couple hours to get the result but still no luck. Commented Sep 19, 2016 at 6:49

2 Answers 2

3

This code should work:

class SomeClass: NSObject {

    var displays: Int
    var id: String

    init(_ id: String, _ displays: Int) {
        self.id = id
        self.displays = displays
    }
}


//Example of filtering

let array = [
    SomeClass("1", 1),
    SomeClass("3", 3),
    SomeClass("4", 7),
    SomeClass("8", 8),
    SomeClass("2", 3),
    SomeClass("7", 2),
    SomeClass("5", 5),
    SomeClass("1", 1),
    SomeClass("3", 4),
    SomeClass("2", 2),
    SomeClass("7", 5),
    SomeClass("6", 8)
]

var resultDictionary: [String : Int] = [:]

for element in array {
    let lastDisplays = resultDictionary[element.id] ?? 0 //if object with this id is first time counted, the resultDictionary[element.id] will return nil and then lastDisplays will be equal to 0

    resultDictionary[element.id] = lastDisplays + element.displays
}

var result = resultDictionary.map { SomeClass($0.key, $0.value) }

In the end the result array will contain SomeClass objects with counted displays.

Because dictionary have only unique keys, we can use it for counting displays sum.

Sign up to request clarification or add additional context in comments.

Comments

1

Try this approach:

class SomeClass: NSObject {
    internal var displays: Int?
    internal var id: String?

    init(displays: Int?, id: String?) {
        self.displays = displays
        self.id = id
    }
}

var array = [
    SomeClass(displays: 2, id: "123"),
    SomeClass(displays: 3, id: "456"),
    SomeClass(displays: 4, id: "123"),
]

var counts: [String: Int] = [:]

for obj in array {
    if let id = obj.id, displays = obj.displays {
        let prevDisplays = counts[id] ?? 0
        counts[id] = prevDisplays + displays
    }
}

print(counts)

EDIT: If you would like to have more functional version of above, I can only come up with the following:

counts = array.reduce([String: Int]()) { dict, item in
    var dict = dict
    if let id = item.id, displays = item.displays {
        dict.updateValue((dict[id] ?? 0) + displays, forKey: id)
    }
    return dict
}

1 Comment

Thanks. Let me quickly try and give you heads up. I am wondering if we can do the same thing with Map, filter and reduce etc.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.