Arrange messed up array - ios

In my app there's an array called newArray that contains a lot of numbers. The app sends the numbers to a server and puts them into a new array called stalkers. My problem is that some names are returned faster than others and the names in the stalkers array could be in any order. How can I make the order of the returned data be the same as the corresponding numbers in newArray?
So let's say newArray = ["10002938948","46789890","2984829389"]. My code sends it to a server and downloads the names. For "10002938948", the server returns "Tim". For "46789890" the server returns "Louis". For "2984829389", the server returns "Rob". Then it should be stalkers = ["Tim","Louis","Rob"], but because they are not downloaded in order (one page loads faster than another), stalkers = ["Louis","Rob","Tim"].
It should be something like I could give each number an id, so I can just sort the id's in the right order in the stalkers array.

Create a dictionary using the elements of newArray as the keys and the arriving name values as the values. When all the results have arrived, create the stalkers array by cycling through newArray, thus keeping the order.
let newArray=["10002938948","46789890","2984829389"]
// For 10002938948, the server returns Tim.
// For 46789890 the server returns Louis.
// For 2984829389, the server returns Rob.
// Then it should be stalkers=["Tim","Louis","Rob"]
// As they arrive, store each result in a dictionary:
var d = [String:String]()
// note that the order of the next three statements doesn't matter!
// Tim arrives for 10002938948
d["10002938948"] = "Tim"
// Louis arrives for 46789890
d["46789890"] = "Louis"
// Rob arrives 2984829389
d["2984829389"] = "Rob"
// now assemble stalkers by cycling through newArray
let stalkers = newArray.map{d[$0]!} // ["Tim","Louis","Rob"]

Related

Update multiple Firebase documents using an array of Document IDs in Swift

I have an array of Strings which represent Firebase Document IDs like so:
var idArray = [“PuLDb90jgz3a5P8bLQoy”, “PMKoZIp46umXQnUlA64a”, “cVGbD3Wy4gWjZ9fZP7h1”]
This Array is dynamic and has been generated by a previous getDocuments call. It could have up to 15 ID strings in it, so it cannot be hard coded.
Within each Firebase Document I have an Int field called menuPosition set to a current value.
What I am trying to do is update each document which appears in the idArray and simply -1 from the menuPosition field value in one go.
What should be so straightforward is driving me crazy - does anyone know a simple way to do it? Obviously, if I put it in a for loop then the code will run too many times and my menuPosition value would be wrong. I just want each operation to perform once.
Any help would be greatly appreciated
Just run a loop over the document IDs and decrement the field in each iteration.
var idArray = ["J2LovReBF0v8F4e0RSBU", "UcW8tsgld2ZuUo92xfP8", "oHTJ4iO1NWCK7x1aryne"]
for docId in idArray {
Firestore.firestore().document("someCollection/\(docId)").updateData([
"menuPosition": FieldValue.increment(Int64(-1))
])
}
If you want this operation to be atomic then just wrap it in a batch write.
var idArray = ["J2LovReBF0v8F4e0RSBU", "UcW8tsgld2ZuUo92xfP8", "oHTJ4iO1NWCK7x1aryne"]
let db = Firestore.firestore()
let batch = db.batch()
for docId in idArray {
batch.updateData([
"menuPosition": FieldValue.increment(Int64(-1))
], forDocument: db.document("someCollection/\(docId)"))
}
batch.commit()

Access data from outside a for loop

I'm iterating over JSON data and taking the data and assigning it to a global variable, when I print the variable within the loop I get all the data, however, when I print the variable outside the loop I'm only getting the last pieces of data from the JSON object. My objective is to take the data and pass it as a parameter of a function. How do I get all the data outside the loop?
var stockParam = [String]()
for info in stockInfo {
self.stockParam = [info.symbol]
print("inside \(stockParam)")
}
print("outside \(stockParam)")
fetchProfileData(stock: stockParam)
Thats because you are setting stockParam as array of one element (info.symbol):
self.stockParam = [info.symbol]
To hold all info symbols in stockParam array you have to append element on every iteration:
for info in stockInfo {
self.stockParam.append(info.symbol)
}
Or simply use map function:
var stockParam = stockInfo.map {$0.symbol}

How to access key from [Any] using swift

Am developing a application using swift,in my am integrating cometchat following the link https://docs.cometchat.com/ios-sdk/quick-start/. So am fetching chat history from the server.
Now I got two(sender messages and receiver messages) nsmutablearray value from the server.
i.e., var firstArr = response!["history"]! as! NSMutableArray
var secondArr = response!["history"]! as! NSMutableArray
I merged two nsmuatblearray values and the result i got is:
[
{
from = 1;
id = 68;
localmessageid = "46A9A5E5-FEEC-4588-B7D6-18E88BA68393_2";
message = "ckeck messages";
"message_type" = 10;
old = 1;
self = 1;
sent = 1521185409000;
},
{
from = 2;
id = 69;
localmessageid = "46A9A5E5-FEEC-4588-B7D6-18E88BA68393_1";
message = "sent to thiyakarajan";
"message_type" = 10;
old = 1;
self = 1;
sent = 1521185410000;
}
]
In the responses key value sent is refered as timestamp.
using that sent key(timestamp) help me to sort array in ascending
order.
And also me to load message value in table view.
Thanks
You can access the Array in cellforrowatindexpath method of your TableView by using code like [[yourarray objectAtIndex:indexPath.row]objectForKey:#"message"]. By using this line you can access the value of message of the array at indexPath 0. Also for sorting the Array depending on timestamp please refer the below code:
NSSortDescriptor* sortOrder = [NSSortDescriptor sortDescriptorWithKey: #"sent" ascending: YES];
return [myArray sortedArrayUsingDescriptors: [NSArray arrayWithObject: sortOrder]];
We have used the same in our ReadyUI code. Please refer our ReadyUI source code and email us at support#cometchat.com if you need additional assistance.
It's a very bad practice working with network data like that. Especially if you want to use this data further inside of your app.
You need to parse the data received either in Dictionary or in your own data structure to work with it safely. There're plenty of ways to do that including JSONSerialization, Codable Protocol or even external libraries like SwiftyJSON
After parsing you will have your objects that you can work with without necessity of casting Any type to expected types, which brings a lot of optional checks. So let's say you have your structure called Message that contains all the data from JSON, after getting all the objects you'll have your neat [Message] array that you can pass around the application.
To sort array by some of the properties you simply use function sorted(by:) that is default for any collection. In your case: sortedArray = myArray.sorted(by: {$0.sent < $1.sent})
Now you can use this array as a dataSource for your tableView using UITableViewDataSource protocol
It's obvious that you're pretty new to iOS programming, so I'd recommend to look up for some tutorials on working with networking data. You can watch this video for example, it pretty much sums up everything mentioned above.
Do code like this
Save Swift Array
var firstArr : Array<Dictionary<String, Any>> = response!["history"]! as! Array<Dictionary<String, Any>>
Access valus
let strMessage : String = fistArr[index]["message"] as! String
Will works..!

How avoid having double loop?

From healthkit, I will receive some datas, for example steps data.
I save in my server this datas. Il have then an array of datas:
1.- startDate, endDate, value
2.- startDate, endDate, value
etc
It can be very lot of values in my server.
Then I get the values in the Healthkit. I have lot of values. Values who are in the server and new values.
I want to upload to the server only the new values.
I do so:
for each value in my server {
for each value in healthkit{
if(startDate, endDate and value are not equal to the value in the server){
then save the value in the server
}
}
}
The algo will work, but it's very very slow. I can have lot of values in the two systems. Most of them the same in the two places.
Have you an idea how to do better?
I cannot save a flag in the healthKit.
I'm using ionic with angular 4 and typescript.
This answer assumes that the data on your server and the data from healthKit are sorted in the same way, or that you can sort them without affecting anything else.
For example you can sort your data on the server and the data from healthKit by StartDate, break ties by EndDate, then break ties by value.
Now you have two sorted arrays that you want to merge. The idea is to use the merge function of merge sort explained here.
You will end up with an array containing all the data without repetitions, which you can save on your server.
Edit:
void mergeArrays(int arr1[], int arr2[], int n1,
int n2, int arr3[])
{
int i = 0, j = 0, k = 0;
// Traverse both array
while (i<n1 && j <n2)
{
// Check if current element of first
// array is smaller than current element
// of second array. If yes, store first
// array element and increment first array
// index. Otherwise do same with second array
if (arr1[i] < arr2[j])
arr3[k++] = arr1[i++];
else if (arr2[j] < arr1[i])
j++;
else
j++,i++;
}
// Store remaining elements of first array (healthKit Array)
while (i < n1)
arr3[k++] = arr1[i++];
}
I think I need a bit more context to understand the problem. By "new" values, are you including entries that have been modified, or just new entries that have been added?
If you only need the new values, and they are being added to the end of the array on the client side, then you can just take them from the end of the array.
const new_count = healthkit.length - myserver.length, // number of new entries
index_start = healthkit.length - new_count, // index in healthkit array where new entries start
new_values = healthkit.slice(index_start); // new array containing only new entries
addNewValues(new_values);
Now you have the new values in a separate array, and you can update them to the server.
If it is the case that you do need to update values that have changed, you can iterate over both arrays (only once, and at the same time) and find the differences. I am going to assume that the entries are in the same index for both arrays. I'm also assuming the "value" key is the only one you want to compare. You can do the following to find the values that have been modified.
const modified_values = [];
myserver.forEach(function(entry, i) { // iterate over server array
let healthkit_entry = healthkit[i]; // get healthkit entry with same index
if(entry.value !== healthkit_entry.value) { // see if value has changed
modified_values.push(healthkit_entry); // if changed, add to modified array
}
});
updateModifiedValues(modified_values);
Now the modified_values array has all of the modified entries from the healthkit array.

Printing Values of dictionary using loop

I trying to print values of dictionary in serial order, like One Two Three but using below code is displaying random value from dictionary. How can i rectify it! Thank you !!
var someDict:[Int:String] = [1:"One", 2:"Two", 3:"Three"]
for keys in someDict.keys
{
//print (keys)
print(someDict[keys]!)
}
Output:
Two
Three
One
And when i print keys. it shows 2 3 1 :(
The keys of the dictionary is no order.
So you can use other Array to save key to ensure order.
Or..
for key in someDict.keys.sort ({
$0 < $1
}) {
print(someDict[key])
}
Chose height performance way according to your demand.

Resources