Type() -> Int cannot conform to BinaryInteger - swift

I am trying to find the number of item bigger than a certain item as follows. However, I am getting the following issue : Type() -> Int cannot conform to BinaryInteger.
I am wondering how I could able to fix it?
extension Array where Element: FloatingPoint {
var biggerItem : Element {
return numberBiggerItems()
}
private func numberBiggerItems() -> Element {
return Element { filter({$0 > 100.0}).count }
}
}

There are three problems in your code:
The return type of your method should be Int, which is what thecount of a collection returns.
The literal 100.0 is interpreted as a Double. You have to use 100 so that it can be a literal for the generic FloatingPoint type.
The return value of filter(...).count must not be wrapped in a closure (this is what causes the seen error message).
Putting it together:
extension Array where Element: FloatingPoint {
var biggerItem : Int {
return numberBiggerItems()
}
private func numberBiggerItems() -> Int {
return filter({ $0 > 100 }).count
}
}
If you really want to return the integer count as an Element then it can be converted with an Element(...) constructor:
extension Array where Element: FloatingPoint {
var biggerItem : Element {
return numberBiggerItems()
}
private func numberBiggerItems() -> Element {
return Element(filter({ $0 > 100 }).count)
}
}

Related

Contain method in a Stack Implementation in swift

Here is a stack implementation I found on the web
public struct Stack<T> {
fileprivate var array = [T]()
public var isEmpty: Bool {
return array.isEmpty
}
public var count: Int {
return array.count
}
public mutating func push(_ element: T) {
array.append(element)
}
public mutating func pop() -> T? {
return array.popLast()
}
public var top: T? {
return array.last
}
}
I wanted a simple contains method to see if an element is in the stack
You have to mark your element as Equatable to check whether element available in array or not. Here Stack<T : Equatable> mark T generic element should be of type Equatable.
Check this code :
public struct Stack<T : Equatable>
{
fileprivate var array : [T] = [T]()
public var count : Int { return array.count }
public var isEmpty : Bool {return array.isEmpty }
public mutating func push(_ element : T) {
array.append(element)
}
public mutating func pop() -> T? {
return array.popLast()
}
public func peek() -> T? {
return array.last
}
public func contains(_ element : T) -> Bool {
return self.array.contains { (arrayElement) -> Bool in
return element == arrayElement
}
}
}
Use of code :
// Create a stack and put some elements on it already.
var stackOfNames = Stack(array: ["Carl", "Lisa", "Stephanie", "Jeff", "Wade"])
// Add an element to the top of the stack.
stackOfNames.push("Mike")
print("Is contains : \(stackOfNames.contains("Carl"))") //true
Here my element is type of String, and String already confirming to type Equatable. So it will work.
extension String : Equatable {
/// Returns a Boolean value indicating whether two values are equal.
///
/// Equality is the inverse of inequality. For any values `a` and `b`,
/// `a == b` implies that `a != b` is `false`.
///
/// - Parameters:
/// - lhs: A value to compare.
/// - rhs: Another value to compare.
public static func ==(lhs: String, rhs: String) -> Bool
}
If you using your custom type and want to make use of Stack then you have to implement Equatable protocol for that class.
Open up a playground to begin implementing your Swift stack!
To start off, write the following into your playground:
struct Stack {
fileprivate var array: [String] = []
}
Pushing an object onto the stack is relatively straightforward. Add the following method inside the stack:
// 1
mutating func push(_ element: String) {
// 2
array.append(element)
}
Popping the stack is also straightforward. Add the following method inside the stack, just under the push method:
// 1
mutating func pop() -> String? {
// 2
return array.popLast()
}
Peeking into the stack is to check the top element of the stack. This should be relatively simple. Swift arrays have a last property that returns it’s last element without mutating itself. Try to do this yourself!
Add the following inside the stack:
func peek() -> String? {
return array.last
}

Swift Protocol Extension with AssociatedType Constrained to Collection, Can't Use Subscript

I'm trying to write a protocol that conforms to the Collection Protocol, and it has an associatedType - Object and a property object.
protocol DDCDataSource: Collection
{
associatedtype Object
var object: Object {get set}
}
I want to add some default functionality for the case where Object also conforms to the Collection protocol, namely just directly return Object's implementation of these required Collection properties and functions. It seems like it all works except for Collection's requirement for a subscript.
Cannot subscript a value of type 'Self.Object' with an index of type 'Self.Object.Index'
extension DDCDataSource where Object: Collection
{
typealias Index = Object.Index
var startIndex: Object.Index {
get {
return object.startIndex
}
}
var endIndex: Object.Index {
get {
return object.endIndex
}
}
subscript(position: Object.Index) -> Element
{
return object[position]
}
func index(after i: Object.Index) -> Object.Index {
return object.index(after: i)
}
}
Short answer: Change the return type of the subscript method
to Object.Element
subscript(position: Object.Index) -> Object.Element {
return object[position]
}
or add a type alias (in a similar way as you did for the Index type)
typealias Element = Object.Element
subscript(position: Object.Index) -> Element {
return object[position]
}
That makes the code compile and run as expected.
Explanation: The subscript method of Collection is declared as
subscript(position: Self.Index) -> Self.Element { get }
where Self.Index and Self.Element are associated types
of `Collection. With your code
subscript(position: Object.Index) -> Element {
return object[position]
}
the compiler infers Self.Index to be Object.Index, but there
is no relation between Self.Element and Object.Element (which is
returned by object[position]). The error becomes more apparent
if you add an explicit cast:
subscript(position: Object.Index) -> Element {
return object[position] as Element
}
Now the compiler complains
error: 'Self.Object.Element' is not convertible to 'Self.Element'; did you mean to use 'as!' to force downcast?
The correct solution is not the forced cast but to make the compiler
know that Self.Element is Object.Element, by adding a type alias
or by changing the return type
subscript(position: Object.Index) -> Object.Element {
return object[position]
}
so that the compiler infers DDCDataSource.Element to be Object.Element.
Full self-contained example: (Swift 4, Xcode 9 beta 6)
(Note that you can omit the get keyword for read-only computed
properties.)
protocol DDCDataSource: Collection {
associatedtype Object
var object: Object { get set }
}
extension DDCDataSource where Object: Collection {
var startIndex: Object.Index {
return object.startIndex
}
var endIndex: Object.Index {
return object.endIndex
}
subscript(position: Object.Index) -> Object.Element {
return object[position]
}
func index(after i: Object.Index) -> Object.Index {
return object.index(after: i)
}
}
struct MyDataSource: DDCDataSource {
var object = [1, 2, 3]
}
let mds = MyDataSource()
print(mds[1]) // 2
for x in mds { print(x) } // 1 2 3
Firstly, I think you should define Element,
Secondly, you use object[position], Object Conforms To Collection , but it is not of Collection Types . Obviously it is not Array.
As apple
says: array
conforms to CustomDebugStringConvertible / CustomReflectable /
CustomStringConvertible / CVarArg /Decodable / Encodable /
ExpressibleByArrayLiteral /MutableCollection /RandomAccessCollection /
RangeReplaceableCollection
I think extension DDCDataSource where Object: Array is better.
And the element in array shall be Element defined. Just tips.
Try this:
subscript(position:Object.Index) -> Element
{
var element: Element
guard let elementObject = object[position] else {
//handle the case of 'object' being 'nil' and exit the current scope
}
element = elementObject as! Element
}

Extensions of generic types in Swift 4

I have two protocols and a generic struct:
public protocol OneDimensionalDataPoint {
/// the y value
var y: Double { get }
}
public protocol TwoDimensionalDataPoint: OneDimensionalDataPoint {
/// the x value
var x: Double { get }
}
public struct DataSet<Element: OneDimensionalDataPoint> {
/// the entries that this dataset represents
private var _values: [Element]
//...implementation
}
extension DataSet: MutableCollection {
public typealias Element = OneDimensionalDataPoint
public typealias Index = Int
public var startIndex: Index {
return _values.startIndex
}
public var endIndex: Index {
return _values.endIndex
}
public func index(after: Index) -> Index {
return _values.index(after: after)
}
public subscript(position: Index) -> Element {
get{ return _values[position] }
set{ self._values[position] = newValue }
}
}
There is a large number of methods that apply to DataSet only when it's Element is a TwoDimensionalDataPoint. So I made an extension like so:
extension DataSet where Element: TwoDimensionalDataPoint {
public mutating func calcMinMaxX(entry e: Element) {
if e.x < _xMin {
_xMin = e.x
}
if e.x > _xMax {
_xMax = e.x
}
}
}
The compiler doesn't like this, and says:
Value of type 'DataSet.Element' (aka
'OneDimensionalDataPoint') has no member 'x'
Shouldn't this be fine since I constrained Element to TwoDimensionalDataPoint in the extension?
After I popped it into Xcode I was able to get a better understanding of what was going on,
Your issue is your type alias is overriding your generic type,
Rename your generic name to T and assign Element to T
public typealias Element = T
or your typealias like:
public typealias DataElement = OneDimensionalDataPoint
or just drop the typealias all together.

Adopting CollectionType (Collection) in Swift

I'm writing a graphics library to display data in a graph. Since most of the projects I do tend to have a large learning component in them, I decided to create a generically typed struct to manage my data set DataSet<T: Plottable> (note here that Plottable is also Comparable).
In trying to conform to MutableCollectionType, I've run across an error. I'd like to use the default implementation of sort(), but the compiler is giving the following error when trying to use the sorting function.
Ambiguous reference to member 'sort()'
Here's a code example:
var data = DataSet<Int>(elements: [1,2,3,4])
data.sort() //Ambiguous reference to member 'sort()'
The compiler suggests two candidates, but will not actually display them to me. Note that the compiler error goes away if I explicitly implement sort() on my struct.
But the bigger question remains for me. What am I not seeing that I expect the default implementation to be providing? Or am I running across a bug in Swift 3 (this rarely is the case... usually I have overlooked something).
Here's the balance of the struct:
struct DataSet<T: Plottable>: MutableCollection, BidirectionalCollection {
typealias Element = T
typealias Iterator = DataSetIterator<T>
typealias Index = Int
/**
The list of elements in the data set. Private.
*/
private var elements: [Element] = []
/**
Initalize the data set with an array of data.
*/
init(elements data: [T] = []) {
self.elements = data
}
//MARK: Sequence Protocol
func makeIterator() -> DataSetIterator<T> {
return DataSetIterator(self)
}
//MARK: Collection Protocol
subscript(_ index:DataSet<T>.Index) -> DataSet<T>.Iterator.Element {
set {
elements[index] = newValue
}
get {
return elements[index]
}
}
subscript(_ inRange:Range<DataSet<T>.Index>) -> DataSet<T> {
set {
elements.replaceSubrange(inRange, with: newValue)
}
get {
return DataSet<T>(elements: Array(elements[inRange]))
}
}
//required index for MutableCollection and BidirectionalCollection
var endIndex: Int {
return elements.count
}
var startIndex: Int {
return 0
}
func index(after i: Int) -> Int {
return i+1
}
func index(before i: Int) -> Int {
return i-1
}
mutating func append(_ newElement: T) {
elements.append(newElement)
}
// /**
// Sorts the elements of the DataSet from lowest value to highest value.
// Commented because I'd like to use the default implementation.
// - note: This is equivalent to calling `sort(by: { $0 < $1 })`
// */
// mutating func sort() {
// self.sort(by: { $0 < $1 })
// }
//
// /**
// Sorts the elements of the DataSet by an abritrary block.
// */
// mutating func sort(by areInIncreasingOrder: #noescape (T, T) -> Bool) {
// self.elements = self.elements.sorted(by: areInIncreasingOrder)
// }
/**
Returns a `DataSet<T>` with the elements sorted by a provided block.
This is the default implementation `sort()` modified to return `DataSet<T>` rather than `Array<T>`.
- returns: A sorted `DataSet<T>` by the provided block.
*/
func sorted(by areInIncreasingOrder: #noescape (T, T) -> Bool) -> DataSet<T> {
return DataSet<T>(elements: self.elements.sorted(by: areInIncreasingOrder))
}
func sorted() -> DataSet<T> {
return self.sorted(by: { $0 < $1 })
}
}
Your DataSet is a BidirectionalCollection. The sort() you're trying to use requires a RandomAccessCollection. The most important thing you need to add is an Indicies typealias.
typealias Indices = Array<Element>.Indices
Here's my version of your type:
protocol Plottable: Comparable {}
extension Int: Plottable {}
struct DataSet<Element: Plottable>: MutableCollection, RandomAccessCollection {
private var elements: [Element] = []
typealias Indices = Array<Element>.Indices
init(elements data: [Element] = []) {
self.elements = data
}
var startIndex: Int {
return elements.startIndex
}
var endIndex: Int {
return elements.endIndex
}
func index(after i: Int) -> Int {
return elements.index(after: i)
}
func index(before i: Int) -> Int {
return elements.index(before: i)
}
subscript(position: Int) -> Element {
get {
return elements[position]
}
set {
elements[position] = newValue
}
}
subscript(bounds: Range<Int>) -> DataSet<Element> {
get {
return DataSet(elements: Array(elements[bounds]))
}
set {
elements[bounds] = ArraySlice(newValue.elements)
}
}
}
var data = DataSet(elements: [4,2,3,1])
data.sort()
print(data.elements) // [1,2,3,4]
You don't actually need an Iterator if you don't want one. Swift will give you Sequence automatically if you implement Collection.

How do I implement custom operator [] in swift

I have written a simple queue class in swift. It's implemented by an Array.
Now I want this performs more like built-in array.So I need to implement the []operator but failed. Somebody help?
public class SimpleQueue<T : Any>
{
private var frontCur = 0
private var reuseCur = -1
private var capacity = 0
private var impl = [T]()
public var count : Int
{
get
{
return impl.count - frontCur
}
}
public func empty() -> Bool
{
return self.count == 0
}
public func size() -> Int
{
return impl.count
}
public func append(o : T)
{
if(frontCur > reuseCur && reuseCur >= 0)
{
impl[reuseCur] = o
reuseCur++
}
else
{
impl.append(o)
}
}
public func pop()
{
frontCur++
}
public func front() -> T
{
return impl[frontCur]
}
public postfix func [](index:Int) -> T //Error!!!!
{
return impl[index + frontCur]
}
}
var x = SimpleQueue<Int>()
for index in 1...10{
x.append(index)
}
print(x.count)
for index in 1...3{
x.pop()
}
print(x.count,x.front(),x[2]) // x[2] Error!!!
apple docs
Subscripts enable you to query instances of a type by writing one or
more values in square brackets after the instance name. Their syntax
is similar to both instance method syntax and computed property
syntax. You write subscript definitions with the subscript keyword,
and specify one or more input parameters and a return type, in the
same way as instance methods.
Subscript is not an operator. Just a method marked with the subscript keyword.
subscript (index:Int) -> T {
return impl[index + frontCur]
}
Read this:
class MyColl {
private var someColl : [String] = []
subscript(index: Int) -> String {
get {
return someColl[index]
}
set(value) {
someColl[index] = value
}
}
}
And read this:
Swift has a well-designed and expansive suite of built-in collection types. Beyond Array, Dictionary, and the brand new Set types, the standard library provides slices, lazy collections, repeated sequences, and more, all with a consistent interface and syntax for operations. A group of built-in collection protocols—SequenceType, CollectionType, and several others—act like the steps on a ladder. With each step up, a collection type gains more functionality within the language and the standard library.