Mission: I need to provide an Array extension method which would compare 2 arrays of raw representables whose raw type conforms to Equatable and say if the arrays contain the same elements by reusing the below pieces of code.
What I have at the moment:
public extension Array {
func containsTheSameElements(as array: [Element], condition: @escaping (Element, Element) -> Bool) -> Bool {
var localCopy = array
let countOfUncommonElements = reduce(0) { (uncommonElementsCount: Int, item: Element) -> Int in
if let index = localCopy.index(where: {condition(item, $0)}) {
localCopy.remove(at: index)
return uncommonElementsCount
} else {
return uncommonElementsCount + 1
}
}
return countOfUncommonElements == 0 && count == array.count
}
}
func enumComparisonClosure<T: RawRepresentable>(firstItem: T, secondItem: T) -> Bool where T.RawValue: Equatable {
return firstItem == secondItem
}
How I'm using it at the moment:
class Somewhere {
enum EnumType: String {
case first
case second
}
func method() {
let firstArray: [EnumType] = [.first, .second]
let secondArray: [EnumType] = [.second]
firstArray.containsTheSameElements(as: secondArray, condition: enumComparisonClosure)
}
}
How I would like to use it:
firstArray.containsTheSameElements(as: secondArray)
How I would like to be able to implement it:
public extension Array {
func containsTheSameElements<Element: RawRepresentable>(as array: [Element]) -> Bool where Element.RawValue: Equatable {
return containsTheSameElements(as: array, condition: enumComparisonClosure)
}
}
How can I constrain the Array's extension "Element" typealias to be a RawRepresentable with RawValue of Equatable type?
Or what would be another approach to make this comparison possible?
The constraints on the extension are separated by a comma, not
by &
. The containsTheSameElements
must take a [T]
argument
where T
is a RawRepresentable
with the same RawValue
as the array elements.
Example:
extension Array where Element: RawRepresentable, Element.RawValue: Equatable {
func containsTheSameElements<T>(as array: [T]) -> Bool
where T: RawRepresentable, T.RawValue == Element.RawValue
{
return self.count == array.count &&
!zip(self, array).contains { $0.rawValue != $1.rawValue }
}
}
Update: It is simpler if you need it only for arrays of the same type:
extension Array where Element: RawRepresentable, Element.RawValue: Equatable {
func containsTheSameElements(as array: [Element]) -> Bool
{
return self.count == array.count &&
!zip(self, array).contains { $0.rawValue != $1.rawValue }
}
}
or, reusing your existing method:
extension Array where Element: RawRepresentable, Element.RawValue: Equatable {
func containsTheSameElements(as array: [Element]) -> Bool
{
return containsTheSameElements(as: array, condition: enumComparisonClosure)
}
}