Iterating over and adding to an array in RxSwift - for-loop

I am making a network request from which I am getting a bunch of users, I am also given a emailDetails object that holds the userId property as well. I am trying to iterate over the users coming from the network request to match up all of the userIds from the emailDetails
I am not sure how to iterate, I know enumerated exists in RxSwift.
self.emailRecipients = networkRequestToGetUser
.asObservable()
.map { users in users.filter {$0.userId ==
emailDetails.userIds }.first }
.map {correctUsers in return correctUsers?.email}
.unwrap()
Error I'm getting: Binary operator '==' cannot be applied to operands of type 'String' and '[String]'

as far as I understand your code snippet, your issue is not actually related to RxSwift. Apparently emailDetails.userIds is an Array of Strings [String]. You could check if the Array contains the userId using this as you mapping instead:
.map { users in users.filter { emailDetails.userIds.contains($0.userId) }.first }
to get the first match. If you want all of them in an Array, just drop the .first and map to the email field:
self.emailRecipients = networkRequestToGetUser
.asObservable()
.map { users in
users.filter {
emailDetails.userIds.contains($0.userId)
}.map { $0.email }
}
to get a Observable of an Array of email addresses. To get the actual adresses, don't forget to subscribe() to that emailRecipients-Observable.

Related

Angular array filter is not working on a list of string

I have an array of string, and want to filter out a particular string after some operation. But, it seems I am doing something wrong there.
this.displayUser.followers.filter(userId=>userId !== this.loggedUser.userid);
Here, followers is an array of string -> string[] and upon some action (say, unfollow); I want to remove the logged user's id from the displayed user's followers list.
However, this filter operation does not seem to work.
On the other hand I tried using splice which is working perfectly fine.
this.displayUser.followers.splice(
this.displayUser.followers.findIndex(userId=>userId === this.loggedUser.userid)
,1);
I am unable to understand what am I doing wrong in the first approach?
Array.filter does not change the array it performs its action on, but returns a new array with values that passed the condition.
In order to use .filter and have the result saved, you can do:
this.displayUser.followers = this.displayUser.followers.filter((userId) => userId !== this.loggedUser.userid);
This will remove all entries where userId === loggedUser.userid.
.splice on the other hand manipulates the array it performs its actions on, hence you will immediately see the results as expected.

Laravel | groupBy returning as object

I am trying to use a Laravel collection to return a groupBy as an array. However, it always seems to be returned as an object no matter what. I have tried to do $posts->groupBy('category')->toArray() but this seems to still return as an object. I have also tried $posts->groupBy('category')->all() and still it is returning as an object.
I don't know if this is something to do with Laravel returning methods within the routes, but I need this to return as an array.
Here is the code:
public function getFeatures($id)
{
return Feature::query()->get()->groupBy('category')->toArray();
}
The actual code is working fine and I'm getting results back but it just doesn't seem to be converting to an array. Thanks.
When doing a query to get (possibly) several items using Eloquent, Laravel will always return an instance of the Collection class that contains all the model objects. If you need them converted to array to use them in a view you could compact the elements. compact will make an associative array of the elements of the collection:
public function getFeatures($id)
{
$features = Feature::all();
return view('my_cool_view', compact($features));
}
On the other hand, if you need them converted to array to return them through an API, Laravel convert the response to JSON by default:
public function getFeatures($id)
{
return Feature::all();
}
Now, if you somehow need the collection converted to an array, just use toArray() like you indicated:
public function getFeatures($id)
{
$collection_of_features = Feature::all();
$array_of_features = $collection_of_features->toArray();
// use it for wherever you want.
}
By reading your comment on other answer, I realized what you mean.
Hi #HCK, thanks for the answer. The ->toArray() method doesn't seem to work and still returns it like { "category_1": [], "category_2": [] } whereas I need it to do ["category_1": [], "category_2": []]
First, this answer is based on a guess that you are doing something like this on your controller (you didn't posted the controller code):
return reponse()->json($theResponseFromGetFeaturesMethod);
Since inside php the $theResponseFromGetFeaturesMethod variable contains an dictionary array (something like ["key"=>"value]), when you convert it to a JSON, you will notice that this "conversion" happens.
This happens because Javascript arrays (and JSON) doesn't support dictionary arrays. See this sample on javascript console:
> var a = [];
undefined
> a['key'] = "value"
"value"
> a
> key: "value"
length: 0
__proto__: Array(0)
Note that the a still have a length of zero, but it now have an key property.
This happens because almost everything on javascript is actually an object. So the array is a special kind of object that have push, pop and many other array methods. Doing array[] = 'somevalue' is actually a shortcut to array.push('somevalue').
So, the behavior that you are observing is right, the toArray() method work as expected, and the JSON conversion too.
Another weird behavior is when you try to convert this PHP array to an JSON:
[
0 => 'a'
1 => 'b'
9 => 'c'
]
You will note that in this case, PHP will convert this array to an object too. The result in JSON will be:
{
"0": "a",
"1": "b",
"2": "c"
}
This is also the expected behavior, since the JSON syntax doesn't support defining the index for a value.

Get to-many relationship property of Managed Object as Array of Managed Objects (not NSOrderedSet)

I have a Collection and a Member Managed Object in Core Data.
Collection has a to-many relationship members, that can contain Member objects. Member objects should be uniquely associated to a single Collection.
I want to be able to use the objects in this relationship as Managed Objects for use in populating my Table View Controller, like so:
let members : [Member] = someCollection.members
However, the members property seems to be an NSOrderedSet? object, and not an array of Member.
To this extent, I have tried the following (found on the internet, as I'm very new to Swift) and I am also trying to catch the situation where the relationship field could be nil. It doesn't work for me, and I don't understand why.
let members = someCollection.members?.array as! [Member]
if members != nil {
//Do something with the array
else {
//handle the case that there is no entry in the relationship field
}
I am getting the following error:
Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
Please help me understand what I am doing wrong, and if possible, provide a solution.
Since array returns a non-optional you have to optional bind members. If the check succeeds you can safely force unwrap the array. The code checks also if the array is not empty.
if let members = someCollection.members, members.count > 0 {
let memberArray = members.array as! [Member]
//Do something with the array
else {
//handle the case that there is no entry in the relationship field
}

How do I get unique field values using rethinkdb javascript?

I have a field which has similar values. For eg {country : 'US'} occurs multiple times in the table. Similar for other countries too. I want to return an array which contains non-redundant values of 'country' field. I am new to creating Databases so likely this is a trivial question but I couldn't find anything useful in rethinkdb api.[SOLVED]
Thanks
You can use distinct, but the distinct command was created for short sequences only.
If you have a lot of data, you can use map/reduce
r.table("data").map(function(doc) {
return r.object(doc("country"), true) // return { <country>: true}
}).reduce(function(left, right) {
return left.merge(right)
}).keys() // return all the keys of the final document

querying a list - returns only one value

I have created a structure and list.
public struct CarMake
{
public string name;
public string id;
}
I added structure objects to this (carMakers) and am trying to query
string selCar = from c in carMakers
where c.name == selectedCarMfgName
select c.id;
I am getting an error near select statement- cannont implicity convert IEnumerable to string. I know that query returns only one value, that's why I have like that.
thanks !
string selCar = (from c in carMakers
where c.name == selectedCarMfgName
select c.id).SingleOrDefault();
Your query returns a collection (with one element). You should use Single() (or SingleOrDefault()) to get that one item. If the query can return more than one result, you should look into First() ( or FirstOrDefault())
Pay attention to the error message. It probably says something like
"cannot implicitly convert IEnumerable<string> to string."
The results of a query of a sequence is another sequence, an IEnumerable<T>. You may know that you expect only one result, but that's not what the query does. To obtain only one result, you can optionally include another extension method on the end.
yourQuery.First();
yourQuery.FirstOrDefault();
yourQuery.Single();
yourQuery.SingleOrDefault();
The difference in these is that the First* variations can work with sequenes with many elements, whereas the Single* variations will throw exceptions if more than one element is present. The *OrDefault variations support the concept of no matching elements, and returns the default value for the type (null in the case of classes, a default value (such as 0 for int) for structs).
Use the version that conforms to your expectation. If you expect one and only one match, prefer Single. If you only care about one out of arbitrarily many, prefer First.
carMakers.Add(new CarMake() { name = "Audi", id = "1234" });
string selCar =(from c in carMakers
where c.name == "Audi"
select c.id).FirstOrDefault();
Output- 1234
I would refactor my query slightly:
var selCar = carMakers.Single(c => c.name == selectedCarMfgName).id;
This assumes you know that the car is in the list. If not, use SingleOrDefault and check the return before getting the id.
I've not done too much with LINQ but because you are selecting into a string you may need to use FirstOrDefault as your statement could return back more than one value yet your string can only hold one.
First will return null value I think if nothing is found but FirstOrDefault will return you a blank string.

Resources