Copying data hidden by interface - interface

I have got some TCP connection which returns some data for me. Also I have got a structure that represents this data.
type Item struct {
A int32
B int32
}
Item supports Unpacker interface
func (item *Item) Unpack(data []int32) {
item.A = data[0]
item.B = data[1]
return
}
type Unpacker interface {
Unpack([]int32)
}
So I receive some data from Network which represents a bunch of items. Now I want to pass my structure to function and I want to get back a slice of structures filled with data:
func find(packet [][]int32, responseItem Unpacker) (items []Unpacker) {
items = make([]Unpacker, len(packet))
for i, data := range(packet) {
responseItem.Unpack(data)
items[i] = responseItem
}
return
}
Of course in this case I have got a slice with a number of identical items (pointers to same item). But I want to get different items and
items[i] = *responseItem
doesn't work in my case.
Here is link to playground: http://play.golang.org/p/RP4ryxoG2I
I believe I didn't understand how Go works (it is my first time with Go). And also good to be noticed: I don't want to use reflection here if it is possible.

You've got unpacker backwards. You want to create new Item in your loop, Unpack into the item and then assign into your slice. You can do this by making find accept a function returning an Unpacker.
See the following: http://play.golang.org/p/rFoa1eoh4A
Your find function:
type UnpackerMaker func() (Unpacker)
func find(packet [][]int32, makeUnpacker UnpackerMaker) (items []Unpacker) {
items = make([]Unpacker, len(packet))
for i, data := range(packet) {
unpacker := makeUnpacker()
unpacker.Unpack(data)
items[i] = unpacker
}
return
}

Related

Swift Realm Results to Editable object or array

OK, I understand that I can not modify the results of a Realm Object.
So what is best way to change the data.
First I get all the Realm data as Results< Month >
let m = Month.getAllEntriesByDateAsc()
Now I need to loop through all the data to modify it. (This is a function to recalculate the entire table data.)
So I want to loop through the data and do something like:
for i in m {
var d = i
// perform calculations like
d.value = 9999
}
I want to do all the modifying on d.
Is these some sort of mapping I can use to create the new edible object from the Realm data?
Previously I did something like this:
for i in m {
let d = Month()
d.value = i.value
d.status = i.status
}
But there are now to many variables.
I guest what I need to so change the Realm Object to the Model object?
And the .toArray() stuff will not work inside the loop? Not sure why.
Thanks.
extension Results {
func toArray<T>(ofType: T.Type) -> [T] {
var array = [T]()
for i in 0 ..< count {
if let result = self[i] as? T {
array.append(result)
}
}
return array
}
}
From here

filter array based on another

I have two arrays, one an array of array of profiles and one of the section names:
var sections: [Array<Profile>] = [friends, contacts, other]
var sectionNames = ["Friends", "Contacts", "Other Users"]
How do I filter the names based on whether the sections are empty? I get an error when I try the code below:
sectionNames.filter { index, _ in
sections[index].count > 0
}
Contextual closure type '(String) throws -> Bool' expect 1 argument, but two given
You can use zip and compactMap:
let nonEmptySections = zip(sections, sectionNames).compactMap { $0.isEmpty ? nil : $1 }
Using zip has the advantage that you don't get crashes if the two arrays have different sizes. On the other hand, it can lead to subtle bugs.
I'd recommend that you use a data structure to model you data instead:
struct Section {
let name: String
let profiles: [Profile]
}
This should ease the way you process the sections in your app. And by using #Alexander's suggestion, you can add an isEmpty property to the struct, making it even easier to use
extension Section {
var isEmpty: Bool { return profiles.isEmpty }
}
... later in the code
let nonEmptySections = sections.filter { !$0.isEmpty }
you can try something like this
var ar1:[Array<Int>] = [[1,2],[3,4,],[],[5,6]]
var ar2 = [1,2,3,4]
ar2 = (0 ..< ar1.count).filter {ar1[$0].count > 0}.map {ar2[$0]}
print(ar2) // [1, 2, 4]

Dictionary in Dictionary value search

I am downloading information from a Firebase database and it is being inputted via a for loop into:
static var Reports = [String:[String:String]]()
I need to figure out a way to search the inside values for a certain string
I have messed around with this but can't seem to get it inside the inside dictionary (If that makes sense)
for values in Reports.count {
if let item = Reports["favorite drink"] {
print(item)
}
}
I need to have a search string then a number of times the value appears like so:
func findString(dict Dictionary) -> Int {
var ReportsLevel1 = 0
(for loop I'm guessing)
search here for string
return ReportsLevel1
}
Tip: the outside dictionary keys are not set in stone, they depend on what time and date the report was submitted
To find out the numberOfTimes in which "yourSearchString" appears you can do as follows
var numberOfTimes = 0
for internalDictionary in reports.values
{
for value in internalDictionary.values
{
if (value == "yourSearchString") { numberOfTimes += 1 }
}
}
or
let numberOfTimes = reports.flatMap { internalDictsArray in internalDictsArray.value.filter { $0.value == "yourSearchString" } }.count

A better approach to recursion?

I built this code sample in Swift Playgrounds as a proof-of-concept for part of a larger project that I'm working on. What I need to do is pass in a series of options (represented by optionsArray or testArray) where each int is the number of options available. These options will eventually be built into 300+ million separate PDFs and HTML files. The code currently works, and puts out the giant list of possibilities that I want it to.
My question is this: Is there a better approach to handling this kind of situation? Is there something more elegant or efficient? This is not something that will be run live on an app or anything, it will run from a command line and take all the time it needs, but if there is a better approach for performance or stability I'm all ears.
Things I already know: It can't handle a value of 0 coming out of the array. The array is a constant, so it won't happen by accident. The way the code down the line will handle things, 0 is a nonsensical value to use. Each element represents the number of options available, so 2 is essentially a Boolean, 1 would be false only. So if I needed placeholder elements for future expansion, they would be a value of 1 and show up as a 0 in the output.
Also, the final product will not just barf text to the console as output, it will write a file in the permutationEnding() function based on the currentOptions array.
let optionsArray: [Int] = [7,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2]
let testArray: [Int] = [7,2,3,2]
var currentOptions: [Int] = []
var outputString: String = ""
func buildPermutations(array: Array<Int>) {
currentOptions.removeAll()
permutationRecursion(array: array, index: 0)
}
func permutationRecursion(array: Array<Int>, index: Int) {
for i in 1 ... array[index] {
currentOptions.append(Int(i-1))
if array.count > (index + 1) {
permutationRecursion(array: array, index: index + 1)
} else {
permutationEnding()
}
currentOptions.removeLast()
}
}
func permutationEnding() {
for i in 1 ... currentOptions.count { // Output Elements
outputString += String(currentOptions[i-1])
}
outputString += "\n" // Goes after output elements closing bracket.
}
// buildPermutations(array: optionsArray)
buildPermutations(array: testArray)
print(outputString)
Thoughts?
I think I've figured out what you're trying to do. You want a string output of every possible integer combination that could map all possible routes on the decision tree.
I got it down to four or five lines.
let n = testArray.count // for readability
let products = ([Int](1...n)).map({testArray[$0..<n].reduce(1, *)})
// products is the cross product of element i + 1 to element n of the array for all i in the array
let zipped = zip(testArray, products)
for i in 0..<testArray.reduce(1, *) { // this reduce is the cross product of the whole array
let treePath = zipped.map(){ String(i / $0.1 % $0.0) }.joined()
outputString += treePath + "\n"
}
One more edit: I think this might be faster with some fancy matrix operations like NumPy. I wonder if the Accelerate framework could do some magic for you, but I have not worked with it.
edit: I was curious so I timed it with this test array
let testArray: [Int] = [7,2,2,2,2,2,2,3,2]
The recursive function in the question was: 132.56 s
The zip-map here was: 14.44 s
And it appears to be exponential as I add elements to the test array.

How to remove duplicate data in the UIPickerView in Swift

May I know how to remove the duplicate data which all the data is passing from the Parse database. I just select one column and pass that column data to this picker view.
I've try to find the query.wherekey but it didn't have the DISTINCT function which similar to the SQL statement, so what should I do to avoid the data duplication?
As you add items one by one into your self.pickerString array, just verify if this array contains or not the new value before addObject new value to the array. For example:
if !self.pickerString.contains(object["Intake"] as! String) {
self.pickerString.append(object["Intake"] as! String)
}
There is no built-in function to remove duplicate items in an array in swift (correct me if I'm wrong). However, you can add new features for array with 'extension' keyword:
extension Array {
func distinct<T: Equatable>() -> [T] {
var newArray = [T]()
for item in self {
if !contains(newArray, item as! T) {
newArray.append(item as! T)
}
}
return newArray
}
}
usage:
let s = ["344","333","1","2","333"]
var p = s.distinct() as [String]
I don't think you have anything like distinct on Parse, you'll have to download all rows and then filter out equal values.
For a functional approach:
func distinct<T: Equatable>(source: [T]) -> [T] {
var unique = [T]()
for item in source {
if !contains(unique, item) {
unique.append(item)
}
}
return unique
}
[...]
self.pickerString = distinct(objects)
[...]