How To Tell How Many Elements Are In A Swift Stack - swift

I am using Swift stacks for my calculator app that I am making. But I need to tell if there is only one element in my stack for my calculator app to function correctly. Does anybody know how to count the number of elements in a Swift stack?
struct Stack {
fileprivate var operators: [String] = []
mutating func push(_element: String) {
operators.append(_element)
}
mutating func pop() -> String? {
return operators.popLast()
}
func peek() -> String? {
return operators.last
}
}

Swift doesn't have a built-in Stack type.
To reveal the size of your custom Stack struct, add a size property to your Stack that returns the number of items in the operators array:
struct Stack {
fileprivate var operators: [String] = []
mutating func push(_ element: String) {
operators.append(element)
}
mutating func pop() -> String? {
return operators.popLast()
}
func peek() -> String? {
return operators.last
}
var size: Int { return operators.count }
}
Example
var stack = Stack()
stack.push("+")
print(stack.size) // 1
_ = stack.pop()
print(stack.size) // 0

Related

Encountered an error in "Generic Where Clauses", still not able to figure out why! While it is same in the swift book

Topic: Generic Where Clauses
protocol Container {
associatedtype Item
mutating func append(_ item: Item)
var count: Int { get }
subscript(i: Int) -> Item { get }
}
struct Stack<Element>: Container {
var items = [Element]()
mutating func push(_ item: Element) {
items.append(item)
}
mutating func pop() -> Element {
return items.removeLast()
}
mutating func append(_ item: Element) {
self.push(item)
}
var count: Int {
return items.count
}
subscript(i: Int) -> Element {
return items[i]
}
}
func allItemsMatch<C1: Container, C2: Container>
(_ someContainer: C1, _ anotherContainer: C2) -> Bool
where C1.Item == C2.Item, C1.Item: Equatable {
if someContainer.count != anotherContainer.count {
return false
}
for i in 0..<someContainer.count {
if someContainer[i] != anotherContainer[i] {
return false
}
}
return true
}
var stackOfStrings = Stack<String>()
stackOfStrings.push("uno")
stackOfStrings.push("dos")
stackOfStrings.push("tres")
var arrayOfStrings = ["uno", "dos", "tres"]
Error comes here in if-else control flow
if allItemsMatch(stackOfStrings, arrayOfStrings) {
print("All items match.")
} else {
print("Not all items match.")
}
Error says that "arrayOfStrings" doesn't conform to the Container Protocol.
Tried many times but not able to figure out
Error exactly says - " Global function 'allItemsMatch' requires that '[String]' conform to 'Container' "
As already mentioned in comments you forgot to declare that Array conforms to the Container protocol.
extension Array: Container { }
Not related to your question but you should also make your Stack structure conform to Sequence as well. It will allow you to use Sequence method elementsEqual
func elementsEqual<OtherSequence>(_ other: OtherSequence) -> Bool where OtherSequence : Sequence, Self.Element == OtherSequence.Element
So just add an index property to your Stack type and implement Sequence next property as follow:
struct Stack<Element>: Container {
typealias Item = Element
var items = [Item]()
mutating func push(_ item: Item) { items.append(item) }
mutating func pop() -> Item { items.removeLast() }
mutating func append(_ item: Item) { push(item) }
var count: Int { items.count }
subscript(i: Int) -> Item { items[i] }
var index: Int = 0
}
extension Stack: Sequence, IteratorProtocol {
mutating func next() -> Item? {
guard index < items.endIndex else { return nil }
defer { index += 1}
return items[index]
}
}
Playground testing:
var stackOfStrings = Stack<String>()
stackOfStrings.push("uno")
stackOfStrings.push("dos")
stackOfStrings.push("tres")
var arrayOfStrings = ["uno", "dos", "tres"]
stackOfStrings.elementsEqual(arrayOfStrings) // true

Is there a built in stack implementation in Swift?

I want to use Stack in my swift code. I couldn't find any inbuilt stack implementation in Swift like java.util.Stack in Java.
I could implement my own Stack in swift but I would prefer a built-in one.
No, but you could implement your own pretty easily
struct Stack {
private var array: [Any] = []
mutating func push(_ element: Any) {
array.append(element)
}
mutating func pop() -> Any? {
return array.popLast()
}
func peek() -> Any? {
guard let top = array.last else { return nil }
return top
}
}
There is an implementation in the documentation at:
https://docs.swift.org/swift-book/LanguageGuide/Generics.html
that is also type agnostic.
struct Stack<Element> {
var items = [Element]()
mutating func push(_ item: Element) {
items.append(item)
}
mutating func pop() -> Element {
return items.removeLast()
}
}
Finally, Apple has released Swift Swift Collections. The Collections package has an implementation of Deque. I can use this as a Stack.
Learned GenericStack with Swift 5.7.1 with Xcode 14:
1. First make a Protocol Stackable :
protocol Stackable {
associatedtype ObjectType
func push(value:ObjectType)
func pop()
func peek()->ObjectType?
}
2. Make a GenericStack class using Stackable :
class GenericStack<T>:Stackable {
private var list:[T] = [T]()
public var elements:[T]{
return list
}
func push(value: T) {
list.append(value)
}
func pop() {
if !list.isEmpty {
list.removeLast()
}
}
func peek() -> T? {
return list.last
}
typealias ObjectType = T
}
3. Use it with any Data Type:
var stackInt:GenericStack<Int> = GenericStack<Int>()
print(stackInt.push(value: 5))
print(stackInt.push(value: 7))
print(stackInt.elements)
var stackChar:GenericStack<Character> = GenericStack<Character>()
print(stackChar.push(value: "A"))
print(stackChar.push(value: "B"))
print(stackChar.elements)
var stackString:GenericStack<String> = GenericStack<String>()
print(stackString.push(value: "Abhi"))
print(stackString.push(value: "test"))
print(stackString.elements)
Video of execution and learning stack in swift : XcodePlaygroundWork

Find an element in a stack data structure swift 4

If found this stack data structure at Ray Wenderlich and it works well:
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'd like to add another method for finding an element within the stack so that I don't try to add an element more than once. For example, I'm keeping a stack of ViewControllers.
var vcStack = Stack<UIViewController>()
vcStack.push(VC1)
vcStack.push(VC2)
I'd like to be able to query the Stack and get back a boolean if the input VC exists (or not), like this:
if vcStack.hasElement(VC1) {
//do something
}
This is pseudo-code - what would the Swift 4 code be?
public var hasElement(_ element: T): -> Bool {
if array.contains(element){
return true
}else{
return false
}
}
If you define your Stack class to require that its elements conform to Equatable:
public struct Stack<T> where T: Equatable {
then your hasElement would be:
public func hasElement(_ element: T) -> Bool {
return array.contains(element)
}
Or you can leave Stack declared as you have it, and add hasElement to an extension:
public extension Stack where T: Equatable {
public func hasElement(_ element: T) -> Bool {
return array.contains(element)
}
}
This allows you have to have a Stack of anything but the hasElement function will only be available if it's a Stack of Equatable values.
struct MenuData {
let title : String!
let imageName : String!
}
class MoreTV: UITableView {
var aryMenu : [MenuData] = [MenuData(title: "My Profile".localized, imageName: "ic-user"),]
}

How can I make this Stack struct define?

I want to make this Stack struct properly.
How can I define 'topItem'?
Is it right to show above "newstack"?
struct Stack {
var Items:[String] = []
mutating func push (item:String){
Items += [item]
}
mutating func pop() -> String {
return Items.removeLast()
}
var topItem =`enter code here`
}
var newStack = Stack()
newStack.push("HistoryListController")
newStack.push("HistoryDetailViewController")
newStack.push("HistoryTimelineViewController")
newStack.push("HistoryChartViewController")
newStack.Items
if let topVC = newStack.topItem {
print("Top View Controller is \(topVC)")
//HistoryChartViewController
}
newStack.pop()
if let topVC = newStack.topItem {
print("Top View Controller is \(topVC)")
//HistoryTimelineViewController
}
I'm very beginner in Swift.
This is my first code
First, items should be lowercase. Second, it's not clear what you want topItem to return. If you want the most recent object, you could implement it like this:
struct Stack {
var items = [String]()
mutating func push (item:String){
items += [item]
}
mutating func pop() -> String {
let result = items[0]
items.removeLast()
return result
}
var topItem : String? {
return items.last
}
}
var newStack = Stack()
newStack.push("HistoryListController")
newStack.push("HistoryDetailViewController")
newStack.push("HistoryTimelineViewController")
newStack.push("HistoryChartViewController")
newStack.topItem // "HistoryChartViewController"
newStack.items
If you want the first object, change it to return items.first.

Access to stored properties of a struct from a extension in Swift

I'm trying to implement a Stack struct in Swift and making it comply to Generator and Sequence.
class Stack<T> {
var items:Array<T>
var depth : Int{ return items.count}
init(){
items = Array<T>()
}
func push(elm:T){
items += elm
}
func pop()->T?{
if depth > 0{
return items.removeLast()
}else{
return nil
}
}
}
I get into trouble when trying to make it comply to Generator. I tried adding a nested type through an extension, that's when I get an error:
extension Stack{
struct StackGenerator: Generator{
var current = 0
mutating func next() -> T?{
let rc = items[current] // Get an error here: can't access items in Stack
}
}
}
The compiler won't let me access the Stack.items property form within StackGenerator. Is this to be expected? How can I work around this?
Generic types can't have nested types - you need to either build StackGenerator outside of your Stack declaration, or use the GeneratorOf<T> type in your generate function.
The first option could look like this:
class Stack<T> : SequenceType {
var items: Array<T>
var depth: Int { return items.count }
init(){
items = Array<T>()
}
func push(elm:T){
items += [elm]
}
func pop()->T?{
if depth > 0 {
return items.removeLast()
} else {
return nil
}
}
func generate() -> StackGenerator<T> {
return StackGenerator(stack: self)
}
}
struct StackGenerator<T>: GeneratorType {
typealias Element = T
var current = 0
var stack: Stack<T>
init (stack: Stack<T>) {
self.stack = stack
}
mutating func next() -> T? {
if current < self.stack.items.count {
return self.stack.items[current++] // Get an error here: can't access items in Stack
}
return nil
}
}