Multidimensional Array Looping in cellForRowAtIndexPath Swift - ios

I have a multidimensional array that I want to display the values of onto one UILabel in each respective cell.
My arrays look like this:
var arrayExample = [["beverages", "food", "suppliers"]["other stuff, "medicine"]]
I'm looping through these values in the cellForRowAtIndexPath in order for it to display on different cells (on a UILabel) the appropriate values:
if let onTheLabel: AnyObject = arrayOfContactsFound as? AnyObject {
for var i = 0; i < objects!.count; i++ {
cell?.contactsUserHas.text = "\(onTheLabel[indexPath.row][i])" as! String
print("arrayOfContactsFound Printing! \(onTheLabel)")
}
}
When printing to the console I get:
arrayOfContactsFound Printing! (
(
beverages,
"supply chain",
pharmacuticals
)
)
But on my label I get "beverages". That's it. How can I get the other 2 values (or X amount if there are more or less than 3 values)?
My for in loop is obviously not doing the trick. Assuming I can optimize/fix that to display all the values?
Thanks in advance.

In your loop you're setting the text of your label multiple times. Each time you set it it doesn't accumulate, it completely replaces the current text with the new text. You'll want something like this:
// Remove the cast and the loop in your code example, and replace with this
let items = arrayOfContactsFound[indexPath.row]
let itemsString = items.joinWithSeparator(" ")
cell?.contactsUserHas.text = itemsString
Another thing to note is your cast doesn't quite make a lot of sense.
var arrayExample = [["beverages", "food", "suppliers"]["other stuff, "medicine"]]
So arrayExample is of type [[String]]. I'm assuming each cell in your table view represents one of the arrays of strings in your array. So each cell represents one [String]. So your items should be arrayExample[indexPath.row]. The cast to AnyObject doesn't make too much sense. If anything you'd be casting it to [[AnyObject]], but there's no reason to because the compiler should already know it's [[String]].

Related

How to Make a Struct Version of the NSCountedSet Class?

I am developing an app in which I need to take two arrays, both holding the same custom data type, MenuItem.
I need to compare them and find the common elements of both arrays.
I compare the two arrays by converting them both to sets and then using the compare function of the set struct.
However, I then need to convert the array of common elements to a Counted Set so that I can find how many of each element exist in the group of common elements.
The problem I am having is with converting the the array of common elements to a Counted Set. In Swift, there is an NSCountedSet class but no CountedSet struct like there are for most built-in swift Data Types:
let groups = Array(self.menu.keys)
//menu and cart are dictionaries the structure [MenuGroup: [MenuItem]]
let cartGroups = Array(self.cart.keys)
let group = groups[indexPath.section]
if cartGroups.contains(group) {
let items = menu[group] as [MenuItem]!
let cartItems = cart[group]
let itemsSet = Set<MenuItem>(items!)
let cartItemsSet = Set<MenuItem>(cartItems!)
let similarSet = itemsSet.intersection(cartItemsSet)
let similarArray = NSMutableArray(Array(similarSet))
let similarCounterSet = NSCountedSet(array: similarArray)
}
I want to create a struct based off the NSCountedSet class so that I can convert the array of common elements to a counted set.
The if statement is for something else, it does not pertain to this question.
Any thoughts on how to do this? If anybody has a different approach to this problem feel free to mention that too.
Thanks,
Simon
Thanks to Martin R I Found An Example of How to do This:
There are various CountedSet implementation available, e.g. https://github.com/0x7fffffff/CountedSet.

Swift 2D Array Initialisation with Objects

I'm Trying to initialise a 2D array with objects in every cell.
I started with a class,
class cell {
var up = 1
var down = 1
var right = 1
var left = 1
}
And then Initialise my Array as such:
let row = Array<cell!>(count: 10, repeatedValue: cell())
let myArray = Array(count: 10, repeatedValue: row)
Now that works fine... Until I change the property of one of the objects.
myArray[0][0].left = 0
Then ALL objects in the Array have their "left" property set to 0.
How can I create objects that are independent of each other in the Array? (without using for-loops to append each item individually)
This won't work with Cell being a class because that is a reference type, so every cell in your array will be a reference to the same cell. If you can, change Cell to be a struct instead of a class. As a value type, every cell will be a unique copy.
If Cell must be a class, you could create myArray using nested maps, (which technically is still loops):
let myArray:[[Cell!]] = (1...10).map { _ in (1...10).map { _ in Cell() } }
Note, you should use names starting with an uppercase letter for class and struct names, which is why I change your cell to Cell.
It's because Cell is a class and classes are reference types. So the first line creates a row with 10 references to the same cell. The second line creates 10 unique rows (arrays are structs therefore value types) but all the unique rows have 10 references to the same cell.
There are several ways to resolve this. You can make sure you create 100 unique cells:
var array = [[Cell]]()
for _ in 0 ..< 10
{
var row = [Cell]()
for _ in 0 ..< 10
{
row.append(Cell())
}
array.append(row)
}
Or, you might consider making Cell a struct which is probably the best idea if a Cell is as simple as your example and you don't need inheritance.
struct Cell
{
var up = 1
var down = 1
var right = 1
var left = 1
}
In which case you can initialise the array the way you expect.
var array = [[Cell]](count: 10, repeatedValue: [Cell](count: 10, repeatedValue: Cell()))
Your class cell works is a reference type. What does that mean ?
Well, Apple's explanation about the topic is quite sufficient :
Types in Swift fall into one of two categories: first, “value types”,
where each instance keeps a unique copy of its data, usually defined
as a struct, enum, or tuple. The second, “reference types”, where
instances share a single copy of the data, and the type is usually
defined as a class. In this post we explore the merits of value and
reference types, and how to choose between them.
By declaring cell as a class, this is a reference type.
Refence type
// let's create an object
let cell1 = Cell()
// now we add a reference to this object
let cell2 = cell1
// now we change the top of cell1
cell1.up = 10
NSLog("\(cell2.up)")
// -> outputs : 10
// Since cell1 and cell2 represents the same object,
// you can't modify cell1 without modifying ce22.
What happen if you declares cell as a structinstead of a class? It becomes a value type :
Value type
// let's create an object
let cell1 = Cell()
// now we create a new object, cell2, with the value initialized
// with cell1's value. It's a copie, not a reference
let cell2 = cell1
// now we change the top of cell1
cell1.up = 10
NSLog("\(cell2.up)")
// -> outputs : 0
// Here cell1 and cell2 are totally different objects
What you are doing won't work. If you try to create an array and populate it repeatedValue and the repeated value is an object, the array contains multiple references to the same object. (Objects are a "reference type". When added to a container what gets added is a reference to the object, not a copy.)
You need to create a new object for each entry in your outer array:
(Edited to create an array of String objects since I don't have access to the OP's cell class)
typealias rowArray = [String!]
var myArray = [rowArray]()
for i in 1...10
{
myArray.append(rowArray(count: 10, repeatedValue: "Foo"))
}
Note that you're going to face the same problem with your inner array. You don't have an array of unique cell objects - you have an array that contains multiple references to a single cell object.

Filter an array by NOT containing string (swift 2)

I am relatively new to swift; I am working on filtering arrays.
I know how to filter out elements of an array that contain a letter (like so: let filteredList = wordlist.filter { !$0.characters.contains(letter) }), but how do I filter out elements that do not have a letter?
Here's what I want to accomplish:
I have a word list in string-array format, i.e. ["thing", "other thing"] (but much longer), and I want to return every element that has a certain letter, filtering out the ones that do not have a certain letter.
Thanks in advance.
This was a silly question, I am sorry. Anyway, I just needed to remove the exclamation mark. So...
let filteredList = wordlist.filter { !$0.characters.contains(letter) }
// returns elements in the array WITHOUT "letter".
let filteredList = wordlist.filter { $0.characters.contains(letter) }
// returns elements in the array WITH "letter".
Thanks Eendje.

trying to populate a cell label with a string from an array

So, I have a cell with one label inside. I am trying to populate that label text with the various items in my array - all strings.
My array
var restauranttypelist: [String] = ["American", "Asian", "Bakery & Deli",
"Burgers", "Italian", "Mexican", "Seafood", "Steakhouse"]
and my cell label text
let type = restauranttypelist [indexPath.row]
var typecell = tableView.dequeueReusableCellWithIdentifier("cellone") as RestaurantTypeCell
typecell.restaurantTypeLabel.text = restauranttypelist.text
return typecell
I have tried a number of solution ranging from ".text" seen above, to ".String", to "restauranttypelist:indexPath.row" to no avail.
I suppose I have two questions. Am I setting up my array correctly? Do I need to insert the "[String]" portion after the variable name?
Finally, how would I be able to set the cell label to the numerous items I have in my array?
Thanks for any help... beginning.
Jon
In let type = restauranttypelist[indexPath.row] you're accessing a String from your Array and storing it in type. Therefore, all you need is typecell.restaurantTypeLabel.text = type.
There's nothing wrong with how you setup the array. You don't need the [String] type annotation since it can be inferred from the value you are assigning to it, but having it there does no harm.
Finally, this doesn't affect how your code works, but it's nice to know anyway:
Swift variable names follow the convention of starting with a lowercase character, and then capitalizing every subsequent word. Following that convention your variable names should be typeCell and restaurantTypeList.

Creating and populating an empty Array

I'm actually learning swift in order to develop iOS apps. I'd like, as an exercise, to create and populate an empty array, that would be filled by using a textfield and a button on the storyboard.
var arr = []
// When button is pressed :
arr.append(textfield.text)
XCode tells me that the append method is not a method of NSArray. So I have used the addObject one, but it is still not correct as the arr variable contains nil.
So here are my three questions :
Is it possible to create an empty array, and if so, how to populate it ?
Sometimes, in my ViewController, when I create a non-empty array, the append method is apparently not valid, and I don't understand why..
Finally, why even though I use the syntax :
var arr = [1] // For example
The arr object is NSArray object and not a NSMutableArray object, making it impossible to add/remove any object that is contained in it?
I hope my questions are clear, if not I'll upload more code of what I'm trying to build,
thank you for your answers !
Try to define your array as a String array, like this:
var arr: [String] = []
And then append to your list, either by:
arr.append("the string")
or
arr += ["the string"]
Empty array can be created using the following syntax.
var emptyArray = [String]()
emptyArray.append("Hi")
see this
You can use following also to add elements to your array.
//append - to add only one element
emptyArray.append("Hi")
//To add multiple elements
emptyArray += ["Hello", "How r u"]
emptyArray.extend(["am fine", "How r u"])
//Insert at specific index
emptyArray.insert("Who r u", atIndex: 1)
//To insert another array objects
var array1 = ["who", "what", "why"]
emptyArray.splice(array1, atIndex: 1)

Resources