Fattie
Fattie

Reputation: 12641

Override count (or whatever) in a SPECIFIC array

Say you have

class Blah {
}

and then I'm going to have [Blah]

However, the Blah array is going to work a bit differently from a normal array.

For example, I want count to work like this, say

override count {
  c = super.count // an ordinary count of the array
  y = count of items where blah.color = yellow
  return y
}

Of course, I know how to override count (or whatever) by subclassing the appropriate array concept in Swift.

But how can I override count "only in" the array [Blah] ... is that possible?

Use case - maybe there's a better way - Blah has a number of concrete subtypes A:Blah, B:Blah .. F:Blah I want to filter [Blah] so it only returns certain of them (say, "B and D types only") when you enumerate, and the count, etc, would only be for the turned-on subtypes. I appreciate Swift's slice and so on could be relevant here.

Upvotes: 1

Views: 274

Answers (1)

user498982
user498982

Reputation:

Like people are commenting, you don't really want to override count. Here's some code that shows why that's not going to work and gives another possible solution.

//: Playground - noun: a place where people can play

class Blah {

    let include: Bool

    init(include: Bool) {
        self.include = include
    }

}

// This code "works", but you'll get an error that "count" is ambiguous because
// it's defined in two places, and there's no way to specify which one you want
//extension Array where Element: Blah {
//
//    var count: Int {
//        return reduce(0) { result, element in
//            guard element.include else {
//                return result
//            }
//
//            return result + 1
//        }
//    }
//
//}

// But you could add a helper to any blah sequence that will filter the count for you
extension Sequence where Iterator.Element: Blah {

    var includedBlahCount: Int {
        return reduce(0) { result, blah in
            guard blah.include else {
                return result
            }

            return result + 1
        }
    }

}

let blahs = [Blah(include: false), Blah(include: true)]
print(blahs.count) // 2
print(blahs.includedBlahCount) // 1

Upvotes: 1

Related Questions