Swift Fill sections & rows in UiTableview - ios

I am trying to fill in a table view from a dictionary data source and tried a lot to achieve desired result but lot of error, need help on this:
this is my test code in playground which almost gives me desired result, but when i try to do same thing in project nothing works:
I have marked my questions next to problem command line:
var sections = Dictionary<String, Array<String>>()
var mySId = ["s1","s2"]
var m``Sdate = ["jun1", "jun2"]
var mEdate = ["jun2", "jun4"]
var mytotalArr = [String]()
var index = 0
for myId in myScId {
mytotalArr.append(mSdate[index]) // transfer data to total array to group
mytotalArr.append(mEdate[index]) // tarnsfer data to total array to group
sections["\(myScId[index])"] = mytotalArr
index++
}
println(sections["sch1"]!) // "[jun1, jun1]"
// in project i do it like this
in cellForRowAtIndexPath
var myarr = sections[indexpath.section]
when i do same as above in project error message // Unresolved Identified indexPath
var mystring = sections["sch1"]!
println(mystring[1]) // "jun1"
Or Please suggest a way to achieve the result as below
Section header = Sch1 ,
row1 = jun1 // mSdate ,
row2 = jun2 // mEdate
section header = Sch2 ,
row1 = jun2 ,
row2 = jun4

Solution for this was not simple to figure out, but i managed using other Stack's.
Basically first you get the value from your first key in Dict, and that search for data witihin it.
little overkill on system and coding, but it works.

Related

Google Sheets Error: The parameters (String) don't match the method signature for SpreadsheetApp.Sheet.getActiveCell

Trying to move data from one sheet to another if two sets of data in each sheet corresponds (the date in this case). I keep getting the following error:
Exception: The parameters (String) don't match the method signature for SpreadsheetApp.Sheet.getActiveRange
I've seen some things to suggest I might not be pulling through from the sheet I've named, or that it's pulling through the value wrong? Not sure, any advice would be great.
Code:
function pullData(){
var ss = SpreadsheetApp.getActiveSpreadsheet()
var inputSheet = ss.getSheetByName("Input");
var currentSheet = ss.getActiveSheet();
var dateCell = inputSheet.getActiveCell("C2").getValue();
var inputRange = inputSheet.getActiveRange("C6:Z999");
var currentRange = currentSheet.getActiveRange("C6:Z999");
if (dateCell == currentSheet.getActiveCell("B2").getValue()){
var inputRows = inputRange.getNumRows();
var inputCols = inputRange.getNumColumns();
for (var i = 1; i <= inputRows; i++) {
for (var j = 1; j <= inputCols; j++) {
var inputValue = inputRange.getCell(i,j).getValue();
var currentValue = currentRange.getCell(i,j).setValue(inputValue);
}
}
}
}
When the value of cell "C2" of the sheet Input is the same with the value of cell "B2 of the active sheet, you want to copy the values of cells "C6:Z999" of the sheet Input to the cells "C6:Z999" of the active sheet.
You want to know the reason of the following error message.
Exception: The parameters (String) don't match the method signature for SpreadsheetApp.Sheet.getActiveRange
Modification points:
getActiveRange() has no arguments. But you use the arguments. I think that the reason of your error message is this.
Also, getActiveCell() has no arguments. So in your script, I think that an error occurs at var dateCell = inputSheet.getActiveCell("C2").getValue();. From this situation, I thought that your tested script might be different from the script in your question.
When I saw the flow of your script, I thought that your goal might be as follows.
When the value of cell "C2" of the sheet Input is the same with the value of cell "B2 of the active sheet, you want to copy the values of cells "C6:Z999" of the sheet Input to the cells "C6:Z999" of the active sheet.
If my understanding is correct, getActiveCell("C2"), getActiveRange("C6:Z999") and getActiveCell("B2") might be getRange("C2"), getRange("C6:Z999") and getRange("B2"), respectively.
Pattern 1:
In this pattern, your script is modified for removing the error message.
Modified script:
Please modify your script as follows.
From:
var dateCell = inputSheet.getActiveCell("C2").getValue();
var inputRange = inputSheet.getActiveRange("C6:Z999");
var currentRange = currentSheet.getActiveRange("C6:Z999");
if (dateCell == currentSheet.getActiveCell("B2").getValue()){
To:
var dateCell = inputSheet.getRange("C2").getValue();
var inputRange = inputSheet.getRange("C6:Z9");
var currentRange = currentSheet.getRange("C6:Z9");
if (dateCell == currentSheet.getRange("B2").getValue()){
Pattern 2:
In this pattern, your script is modified by reducing the process cost. In your current script, getValue() and setValue() are used in the for loop. In this case, when inputRows and inputCols are large, the process cost will be high. So in this pattern, I would like to propose to reduce the cost.
Modified script:
Please modify your script as follows. In this modification, the values of cells "C6:Z999" of the sheet Input are copied to the cells "C6:Z999" of the active sheet using copyTo. By this, your goal can be achieved without using the for loop.
function pullData(){
var ss = SpreadsheetApp.getActiveSpreadsheet()
var inputSheet = ss.getSheetByName("Input");
var currentSheet = ss.getActiveSheet();
var dateCell = inputSheet.getRange("C2").getValue();
var inputRange = inputSheet.getRange("C6:Z9");
var currentRange = currentSheet.getRange("C6:Z9");
if (dateCell == currentSheet.getRange("B2").getValue()){
inputRange.copyTo(currentRange, {contentsOnly:true}); // Modified
}
}
References:
getActiveRange()
getActiveCell()
copyTo(destination, options)

How to append an array to an array at current index?

I have an array myarray and I am using a for loop to get a few information which I add to myarray. But next time the for-loop runs, I don't want to create a separate index, but instead the 2nd time and so on, I want to append the information to myarray[0].
How do I do that?
var myarray = [String]()
for var j in 0 < 12 {
// do some stuff
for var i in 0 ..< 10 {
let parta = json?["users"][j]["name"].string
let partb = json?["users"][j]["Lname"].string
let partc = json?["users"][j]["dob"].string
myarray.append("\(parta)-\(partb)-\(partc)---")
// Here when the for loop comes back again (i = 1) , i dont want to make
// myarray[1] , but instead i want myarray[0] ,
// having value like [parta-partb-partc--parta-partb-partc]
}
}
Basically what I am trying to do is, append the new name/lname/dob values at myarray[0] without affecting the current value/string at myarray[0].
You can insert single element and also add array as below.
Swift 5
var myarray = [String]()
myarray.insert("NewElement", at: 0)
myarray.insert(contentsOf: ["First", "Second", "Third"], at: 0)
If I understand your question correctly, you want to create one long string and add the new data always at the beginning of the string. One way to do that would be:
// Store somewhere
var myString = String()
for var i in(0..<10) {
let parta = json?["name"].string
let partb = json?["Lname"].string
let partc = json?["dob"].string
let newString = "\(parta)-\(partb)-\(partc)---")
newString.append(myString)
myString = newString
// Here when the for loop comes back again (i = 1) , i dont want to make
//myarray[1] , but instead i want myarray[0] ,
//having value like [parta-partb-partc--parta-partb-partc]
}

How to sort NSmutableArray from one of it indexes (lat lng coordinates) in Swift

I'm new in swift and I'd know how to do that in php, but I'm lost with all those dictionaries and I have no idea how to do that in swift 2. I've been googling for a while and didn't found what I need.
I'm parsing a jSon and storing it's values in an NSMutableDictionary in a loop and at the end of the loop I store the NSMutableDictionary in an NSMutableArray, so at the end I have an NSMutableArray with 43 elements, and each element have about 10 keys with their values. I need to sort those 43 elements from their "distance" key and sort them descending. I don't know if that is posible with this current approach. The value of the key "distance" is an int number (meters). I don't know if to use an NSMutableDictionary inside an NSMutable Array is the correct approach to do this but I'm using it because it is possible to have string keys, and not numbers indexes, so for me it's easier to access the key "distance" than the index 8...
First I load the jSon content:
private func parseJson(json : NSMutableArray, tableView : UITableView){
var c : Int = 0
for j in json {
var jsonValues = NSMutableDictionary()
//Create main value
guard let value = j.valueForKey("value")?.valueForKey("value")! else{
continue
}
//Get name
guard let Name : String = (value.valueForKey("Name")?.valueForKey("en") as? String) else {
continue
}
jsonValues["name"] = Name
//more code like this....
TableData.append(Name)
nsDict.insertObject(jsonValues, atIndex: c)
c += 1
}
this is my NSMutableArray content after being loaded:
And this is the code I have this far. Im trying to load the sorted content in a new array, but in this new array some keys are missing.
//Reorder Array by shop distance from user...
var sortDescriptor:NSSortDescriptor = NSSortDescriptor(key: "distance", ascending: true)
var sortedArray : NSArray = nsDict.sortedArrayUsingDescriptors([sortDescriptor])//Crashes
print(sortedArray)
I've managed to sort the array with this technique:
created a new class with for my array
import Foundation
class JsonArrayValues {
init(){
}
var name = String()
var distance = Float()
var lat = Float()
var lng = Float()
var openingTime = String()
var country = String()
var code = String()
var address = String()
var categories = String()
var city = String()
var type = String()
var brands = String()
}
I instantiated one before the loop:
var jsonArrData : [JsonArrayValues] = []
And another one inside the loop, in which I've added the values:
var c : Int = 0
for j in json {
var jsonValues : JsonArrayValues = JsonArrayValues()
//Get name
guard let Name : String = (value.valueForKey("Name")?.valueForKey("en") as? String) else {
continue
}
jsonValues.name = Name
//more code...
jsonArrData.append(jsonValues)
c += 1
}
And finally I've been able to call the function to reorder the array:
//Reorder Array by shop distance from user...
jsonArrData.sortInPlace({$0.distance < $1.distance})
One of your first steps in any non-trivial project really should be to spend some time looking around on github for tools that simplify your problem. In this case, you'd find there are so very many tools to simplify working with JSON in Swift. I'd suggest you look at EVReflection and Gloss particularly, although there are also many people who use SwiftyJSON.
You don't mention how you're accessing the network; you could look at AFNetworking or Alamofire. The latter also has AlamofireJsonToObjects to help.
I also found JSONExport to be incredibly useful.
You'd be spending a lot less time futzing with details as in this unfortunate question and more getting on with your larger goal.

Finding and combining duplicate entries in an array

Im new here so correct me if I've formatted this incorrectly (also new to swift) but basically what I'm trying to do is take an array of dates and numbers and if any of the dates are the same combine the numbers into one entry.
so this
//This is how i format the data after i pull it from core data
var dateAndEntry = [(String, Double)]
//i've split them into two seperate arrays for sorting, but I feel like theres a better way i don't know
var dates = ["01/01/2016", "02/01/2016", "02/01/2016", "04/01/2016", "05/01/2016", "06/01/2016","07/01/2016","07/01/2016"]
var entries = [-14,2,8,9,-1,8,25,6]
becomes this
var dates = ["01/01/2016", "02/01/2016", "04/01/2016", "05/01/2016", "06/01/2016","07/01/2016"]
var entries = [-14,10,9,-1,8,19]
I've tried doing this but i can only get it so that it makes a new array that only contains the new values rather than allowing me to get the duplicated values, combine, insert at index then delete original entries in the two arrays.
func combineDuplicates(dates: [String]) -> [String]{
var output: [String] = []
var checked = Set<String>()
for date in dates {
if !checked.contains(date) {
checked.insert(date)
output.append(date)
}
}
print(output)
return output
}
let sorted = combineDuplicates(dates)
print(sorted)
and yes i have looked on google and here for answers but turned up nothing.
Any solutions, explanations, help, pointers or references to other questions or sources I may have missed would all be greatly appreciated.
This will get you a dictionary with keys the dates and values the sum of entries for each date:
dates.enumerate().reduce([String:Int]()) { dict, item in
var dict = dict
dict[item.1] = (dict[item.1] ?? 0) + entries[item.0]
return dict
}
// ["06/01/2016": 8, "04/01/2016": 9, "01/01/2016": -14, "05/01/2016": -1, "07/01/2016": 31, "02/01/2016": 10]

Xcode Swift - How to initialize a 2D array of [[AnyObject]] of as many elements you want

I know I can initialize an array of Ints for example like:
var intArray = [Int](count: 10, repeatedValue: 0)
What I want to do is something like this:
var array = Array(count:6, repeatedValue:Array(count:0, repeatedValue:AnyObject()))
(Xcode returns with: AnyObject cannot be constructed because it has no accessible initializers)
With the same outcome as I could initialize the array like:
var anyObjectArray : [[AnyObject]] = [[],[],[],[],[],[]]
But doing the above is ugly if i need like 100 rows of lets say 3
The problem is I can append in my function like:
// init array
var anyObjectArray : [[AnyObject]] = [[],[],[]]
//inside a for loop
anyObjectArray[i].append(someValue)
That works ok, until of course i gets higher then the number of rows in the array.
A answer to this problem is also acceptable if I could do something like:
anyObjectArray[append a empty row here][]
But that is probably stupid :)
I hope there is a way to do this cause I don't feel like having a line like:
var anyObjectArray : [[AnyObject]] = [ [],[],[],[],[],[],[],[],[],[],[],[],[],[],[], ... etc ]
at the top of my page ;)
Thank you for your time!
You don't need the second repeatedValue initialiser, since you want an empty array. You can just use
var array = Array(count:6, repeatedValue:[AnyObject]())
You can try with 2 loops, working as a grid :
var items: = Array<Array<Item>>()
for col in 0..<maxCol {
var colItems = Array<Item>()
for row in 0..<maxRow {
colItems.append(Item())
}
items.append(colItems)
}
//Append as much as you want after
Try this
let columns = 27
let rows = 52
var array = Array<Array<Double>>()
for column in 0... columns {
array.append(Array(count:rows, repeatedValue:Int()))
}
Try using this
let array = Array(count:6, repeatedValue:[])
for (var i=0; i<array.count; i++){
array[i] = Array(count:0, repeatedValue: AnyObject.self)
}
in place of your code.
Swift 3:
var array = Array(repeating:[AnyObject](),count:6)

Resources