Finding and combining duplicate entries in an array - ios

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]

Related

Compare the elements in the array to see if there are duplicates in the string

Currently, I'm having a problem comparing an array with a string. I have 2 arrays and want to find out if the elements in those 2 arrays are in the string
let resultString = "STEREON10.000 4ailthameGrinreD NOCHIMINNICHNUÖC-LOINHÀ GIAIDACBIET2ty UnOMMOSTCRShitConDONG FlimChineCrJ045 Dòketquásoan: XSHCM goi 7181 8186-8110°593364THUBAY6A7 05-6-2021teIntaiKNInTaiChínhTP.HCM"
let code_province:[String] = ["xsag", "xsbd", "xsbdi", "xsbl","xsbp",
"xsbt", "xsbth", "xscm", "xsct", "xsdl",
"xsdlk", "xsdn", "xsdng", "xsdno", "xsdt",
"xsgl", "xshcm", "xshg", "xskg", "xskh",
"xskt", "xsla", "xsmb", "xsnt", "xspy",
"xsqb", "xsqng", "xsqnm", "xsqt", "xsst",
"xstg", "xstn", "xstth", "xstv", "xsvl",
"xsvt", "xsbri",]
let name_Province:[String] = ["angiang","binhduong","binhdinh","baclieu", "binhphuoc","bentre", "binhthuan", "camau", "cantho", "dalat","daklak", "dongnai", "daNang", "daknong", "dongthap","gialai", "hcm", "haugiang", "kiengiang", "khanhhoa","kontum", "longan", "mienbac", "ninhthuan", "phuyen","quangbinh", "quangNgai", "quangnam", "quangtri", "soctrang","tiengiang", "tayninh", "thuat.hue", "travinh", "vinhlong","vungtau","baria"]
Here is one way:
let f: (String) -> String? = { resultString.localizedStandardContains($0) ? $0 : nil }
let provincesInResult = code_province.compactMap(f)
let namesInResult = name_Province.compactMap(f)
We map the list of things to search for from a list of strings, to nil if not found and the string if found. Then we compact the result to leave us with just a list of the found ones. That may be 0, 1 or more, so consider those possibilities.

Swift Map ARRAYS by Date Array

Im trying to accomplish this: [Swift2 - Sort multiple arrays based on the sorted order of another INT array
But I have to sort by NSDate array.
// dates are actual NSDates, I pasted strings into my sample
var dates:[NSDate] = [2019-12-20 13:00 +0000, 2019-12-20 13:00 +0000, 2019-12-12 13:00 +0000]
var people:[String] = ["Harry", "Jerry", "Hannah"]
var peopleIds:[Int] = [1, 2, 3, 4]
// the following line doesn't work.
// i tried a few variations with enumerated instead of enumerate and sorted instead of sort
// but with now luck
let sortedOrder = dates.enumerate().sort({$0.1>$1.1}).map({$0.0})
dates = sortedOrder.map({points[$0]})
people = sortedOrder.map({people[$0]})
peopleIds = sortedOrder.map({peopleIds[$0]})
Change your dates declaration from NSDate to Date. Date conforms to Comparable protocol since Swift 3.0. Doing so you can simply sort your dates dates.sorted(by: >). To sort your arrays together you can zip your arrays, sort it by dates and map the sorted elements:
let sortedZip = zip(dates, zip(people, peopleIds)).sorted { $0.0 > $1.0}
let sortedPeople = sortedZip.map{ $0.1.0 }
let sortedIDs = sortedZip.map{ $0.1.1 }
If you are trying to sort associated fields you should really consider using an object oriented approach using some kind of model, however, the following should achieve what you are trying to do:
var n = min(dates.count, people.count, peopleIds.count)
var tuples = (0 ..< n).map { (dates[$0], people[$0], peopleIds[$0]) }
.sorted { $0.0 as Date > $1.0 as Date }
dates = tuples.map{ $0.0 }
people = tuples.map{ $0.1 }
peopleIds = tuples.map{ $0.2 }

how to store values in a 1D array into a 2D array in Swift 4

Hi I would like to store values of a 1D array into a 2D array.
My 1D array has 50 elements and I want to store it in a 5x10 array, but whenever I do that, it always gives me a "Index out of range" error
Any help would be appreciated thanks!
var info2d = [[String]]()
var dataArray = outputdata.components(separatedBy: ";")
for j in 0...10 {
for i in 0...5 {
info2d[i][j] = dataArray[(j)*5+i]
print(info2d[i][j])
}
}
Lots of error in your code.
info2d must be initialised with default values before using it by index
// initialising 2d array with empty string value
var info2d = [[String]](repeating: [String](repeating: "", count: 10), count: 5)
Secondly for loop with ... includes the last value too, use ..<
for j in 0..<10 {
//...
}
Thirdly (j)*5+i is incorrect too.
Better Read how to use arrays, collections and for loop in swift.
https://docs.swift.org/swift-book/LanguageGuide/ControlFlow.html
https://docs.swift.org/swift-book/LanguageGuide/CollectionTypes.html
I would make use of ArraySlice for this.
var arr2D = [[String]]()
for i in 0..<5 {
let start = i * 10
let end = start + 10
let slice = dataArray[start..<end] //Create an ArraySlice
arr2D.append(Array(slice)) //Create new Array from ArraySlice
}

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.

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