Swift: How to define a fixed array of flexible String array - arrays

I already have several arrays for strings. I want to add them to a list of arrays, so I can use a predefined (enum) index. The individual arrays are already in place, I only need to access them via index (fixed with enum or within a loop with index from enum type). So there should be no copy of the strings within the array, only a reference to the array itself.
I already have this in mind:
enum TypeOfArray: Int {
case Src = 0, Dest, SrcCache, DstCache, N
}
var srcFolders : [String] = []
var dstFolders : [String] = []
var srcFoldersCache : [String] = []
var dstFoldersCache : [String] = []
var allFolders: [[String]] = []
Then I want to initilaze the main array by assigning each of the individual arrays. But this is rejected by the compiler: ("Cannot subscript a value of type '[[String]]' with an index of type 'TypeArray'")
allFolders[TypeOfArray.Src] = srcFolders
I don't know if this "typesave" index is even possible.
Can I use a fixed index range 0..N when defining for optimizing memory or speed?
Any ideas?

A dictionary would be a good solution for this:
var dict = [TypeOfArray:[String]]()
dict[TypeOfArray.Src] = srcFolders

Singleton
If you want to share the content of your arrays, an you want the updates to be reflected in your code, you can use a Singleton
final class ImageNameManager {
static let sharedInstance = ImageNameManager()
var srcFolders: [String]
var dstFolders: [String]
var srcFoldersCache: [String]
var dstFoldersCache: [String]
private init() {
// populate: srcFolders, dstFolders, srcFoldersCache, dstFoldersCache
srcFolders = []
dstFolders = []
srcFoldersCache = []
dstFoldersCache = []
}
enum ImageType: Int {
case Src = 0, Dest, SrcCache, DstCache
}
func imageNames(imageType: ImageType) -> [String] {
switch imageType {
case .Src: return srcFolders
case .Dest: return dstFolders
case .SrcCache: return srcFoldersCache
case .DstCache: return dstFoldersCache
}
}
}
Usage
Now you can populate one of your array
ImageNameManager.sharedInstance.dstFolders.append("Hello")
and receives the new data in another section of your code
let dstFolders = ImageNameManager.sharedInstance.imageNames(.Dest)
// ["Hello"]
Update
In order to share the same array across your app you cal also use this code
final class ImageNameManager {
static let sharedInstance = ImageNameManager()
var srcFolders: [String] = []
var dstFolders: [String] = []
var srcFoldersCache: [String] = []
var dstFoldersCache: [String] = []
}
Now alway reference it the array with this code ImageNameManager.sharedInstance.dstFolders, look
ImageNameManager.sharedInstance.dstFolders.append("Hello")
ImageNameManager.sharedInstance.dstFolders.append("World")
ImageNameManager.sharedInstance.dstFolders // ["Hello", "World"]

Related

How to use two-dimensions array in Swift?

So I have this array var arrayItinerario: Array<Any> = [] which is intended to hold arrays of type Itinerario, var temporalArray: Array<Itinerario> = []
Next, this arrayItinerario would later be used to access properties from the struct Itinerario from where the array temporalArray type comes from.
cell.siteLabel.text = "\([arrayItinerario[indexPath.section]][indexPath.row].ubicacion)"
The problem is that arrayItinerario is not an Itinerario type object which make it impossible to access ubicacion to make an example
I have tried
let object = [arrayItinerario[indexPath.section]][indexPath.row] as! Itinerario
But the cast throws an error. How can I do to access properties from the arrays temporalArraythat are inside arrayItinerario?
Note: I am using indexPath because I am filling table cells
var arrayItinerario: [[Itinerario]] = []
//fill data
var temporalArray: [Itinerario] = []
arrayItinerario.append(temporalArray)
cell.siteLabel.text = "\(arrayItinerario[indexPath.section][indexPath.row].ubicacion)"
or
var arrayItinerario: Array<Any> = []
var temporalArray: Array<Itinerario> = []
guard let temp = arrayItinerario[indexPath.section] as? Array<Itinerario>{
return
}
cell.siteLabel.text = "\(temp[indexPath.row].ubicacion)"
Here's an implementation I've used in a few projects:
import Foundation
class Array2D<T> {
var cols:Int, rows:Int
var matrix:[T?]
init(cols: Int, rows: Int, defaultValue:T?) {
self.cols = cols
self.rows = rows
matrix = Array(repeating: defaultValue, count: cols*rows)
}
subscript(col:Int, row:Int) -> T? {
get{
return matrix[cols * row + col]
}
set{
matrix[cols * row + col] = newValue
}
}
func colCount() -> Int { self.cols }
func rowCount() -> Int { self.rows }
}
Because it's generic you can store whatever type you like in it. Example for Ints:
// Create 2D array of Ints, all set to nil initially
let arr = Array2D<Int>(cols: 10, rows: 10, defaultValue: nil)

Array not being seen in scope Im not sure why SwiftUI

Code:
extension Array {
// Total Together An Array
func FindTotal(_ arrayName: [Int]) -> Int {
var currentValue: Int = 0
for i in 0...Int(arrayName.count - 1) {
currentValue = currentValue + Int(arrayName[i])
}
return currentValue
}
// Number Grabber for Calculating the values
func calcItemsD(_ TargetArray: [String]) {
var placeholder: String? = nil
for i in 0...Int(TargetArray.count - 1) {
placeholder = String((TargetArray[i]).character(at: 0)!)
if (placeholder == "1") {
dealerNums.append("")
}
}
}
}
class DeckSetup : ObservableObject {
#Published public var deckOCards: [String] = []
#Published public var yourhand: [String] = []
#Published public var dealerHand: [String] = []
#Published public var dealerNums: [Int] = [7, 2]
#Published public var playerNums: [Int] = []
}
The dealerNums.append("") is throwing the error of out of scope and I am not sure why Heres the all the code that should be relevant.
dealerNums is an array encapsulated in your DeckSetup class. You can't access that from an Array extension.
What you can do, is pass in dealerNums into the function, like so:
func calcItemsD(_ targetArray: [String], dealerNums: inout [Int]) {
var placeholder: String? = nil
for i in 0 ..< targetArray.count {
placeholder = String(targetArray[i].first!)
if placeholder == "1" {
dealerNums.append("")
}
}
}
And called like so from inside your DeckSetup class:
calcItemsD(["1", "K", "A"], dealerNums: &dealerNums)
dealerNums is marked inout, since you are mutating it within the function.
I cleaned up the function a tiny bit, but I don't know if you have more to it. For example, these are more things you could change to improve it:
Iterate with for target in targetArray instead of using the index.
placeholder is not needed to be stored outside the loop as it isn't used. You can have a local let placeholder = ... if needed.
Don't force unwrap (!) the first character. Provide a suitable alternative or fallback.

Trying to loop over an array of Custom class objects

I have a data mod that looks like this:
class CurrencyModel {
var currencyName = ""
var currencyCode = ""
}
I'm trying to loop over all of these objects and create an array of currencyNames.
Here is how I'm trying to do that:
var currencies = [CurrencyModel]()
override func viewWillAppear(_ animated: Bool) {
for names in currencies{
let name = currencies[names].currencyName
namesArray.append(name)
print(namesArray)
}
}
I keep getting this error:
Cannot subscript a value of type '[CurrencyModel]' with an index of type 'CurrencyModel'
currencies is a [CurrencyModel] (an array of CurrencyModel).
The loop for names in currencies iterates that array. names will be each individual CurrencyModel object in the array.
So the line:
let name = currencies[names].currencyName
should be:
let name = names.currencyName
Of course the entire for loop can be replaced with one line:
let namesArray = currencies.map { $0.currencyName }
The problem is here
let name = currencies[names].currencyName
as currencies is an array ( [CurrencyModel]) to subscript it needs an integer value like currencies[0] , but you send names instead which is of type CurrencyModel
You need
var namesArray = [String]()
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
namesArray = currencies.map{$0.currencyName}
}
OR
currencies.forEach { namesArray.append($0.currencyName)}
OR
for names in currencies { // not perferred
namesArray.append(names.currencyName)
}
//
Edit: then use
namesArray = Array(currencies.map{$0.currencyName}.prefix(1))

How eliminate duplicate objects from array of objects in swift

I am having two arrays coming from web service, I need to find out whether the Array2 has the same objects as Array1.
So, For this I am using below code:
var arr1 = [CustomObject]()
var arr2 = [CustomObject]()
var arr3 = [CustomObject]()
var arr4 = [CustomObject]()
self.arr3 = self.arr1 + self.arr2 //concatenate two arrays
self.arr4 = Array(Set(arr3)) // find out uniq values
// below is the extension
extension Array where Element : Hashable {
var unique: [Element] {
var uniqueValues: [Element] = []
forEach { item in
if !uniqueValues.contains(item) {
uniqueValues += [item]
}
}
return uniqueValues
}
}
But it is showing error on above line "Array(Set(arr3))"
Error Is :- To add value to Set
Try this :
var arr1 = ["A","B","C"]
var arr2 = ["A","B","C"]
if Set(arr1).symmetricDifference(arr2).isEmpty {
print("The Arrays Match")
}
Overview:
In order for the set to store custom class / struct, the custom class / struct needs to to conform to Hashable protocol and indirectly Equatable protocol.
Given below is an example using a struct, you can use a class as well.
Code:
struct CustomObject : Hashable{
var something : Int //It is just an example, this could be any type, but some how you should find a way to compute the hash value.
//MARK: Hashable
var hashValue: Int {
return something
}
}
//MARK: CustomObject - Equatable
func ==(lhs: CustomObject, rhs: CustomObject) -> Bool {
return lhs.something == rhs.something
}

Swift: Get multiple array values like "x"

For example, I have an array like var myArray = ['player_static.png', 'player_run0.png', 'player_run1.png', 'player_run2.png', 'player_jump0.png', 'player_jump1.png']
Is there any simple way to get only the "player_runX.png" images?
You can use filter to get all elements that hasPrefix("player_run"):
let myArray = ["player_static.png", "player_run0.png", "player_run1.png", "player_run2.png", "player_jump0.png", "player_jump1.png"]
let playerRuns = myArray.filter{$0.hasPrefix("player_run")}
print(playerRuns) //["player_run0.png", "player_run1.png", "player_run2.png"]
One way to do this would be to iterate over the array and retrieve the elements that match the pattern. A very quick sample would be something like this:
var myArray = ["player_static.png", "player_run0.png", "player_run1.png", "player_run2.png", "player_jump0.png", "player_jump1.png"]
func getSubArray(array:[String],prefix:String) -> [String]
{
var newArray = [String]()
for img in array
{
if img.substringToIndex(img.startIndex.advancedBy(prefix.characters.count)) == prefix
{
newArray.append(img)
}
}
return newArray
}
var test = getSubArray(myArray, prefix: "player_run")

Resources