Im trying to find a good way to sort people by their Role within a specific company. What makes it tricky, is that a person can have one or more roles in different companies.
At the moment I have an array of 'Person' objects, and each of these objects has a NSSet of 'Roles' objects associated to it.
Similar to this:
Person
-personId
-personName (NSString)
-personRoles (NSSet)
Role
-roleId (NSNumber)
-roleWeight (NSNumber)
-roleName (NSString)
-companyId (NSNumber)
I need some code that is able to solve something similar to this:
Sort Array of Person by Role.roleWeight Where Role.companyId = X
I have been looking at the Sort Descriptors, but they dont seem to be enough to solve the challenge. Any suggestions are welcome.
You'll want to look at this
How to sort an NSMutableArray with custom objects in it?
The basic idea is that given any two Person objects, you have to say how they compare. Is one less, greater, or are they the same.
- (NSComparisonResult)compare:(id)otherObject {
// get the role for self
// get the role for other object
// compare their weights
// return the right result
}
To pass in the company id, I think you'll need sortUsingFunction:context:, with a function like this
static int comparePersonsUsingCompanyID(id p1, id p2, void *context)
{
// cast context to a company id
// get the role for p1
// get the role for p2
// compare their weights
// return the right result
}
Assuming that you use NSArray to store data (on maybe CoreData store) you can use NSArrayController. Controller supports sort descriptors and NSPredicate as well. In your case you need a predicate to filter people (where role.companyId = x) and sort descriptors to sort by roleWeight.
Related
I am fairly new to core data. I have database which contains articles with different categories. I want to fetch data from multiple categories, which can be selected by user on the fly. Now I have NSArray which contains selected multiple categories (count from 1 to n) I want to add predicate for selected categories but I'm not able to do so. as per my knowledge i have added for loop for adding categories in predicate but it is not working.
for i in 0...(catArray?.count)!-1 {
let str = String(format:"catId = %#",(catArray?.object(at: i) as? NSNumber)!)
predicateString = predicateString+str
}
let dP = NSPredicate(format:"%#",predicateString)
fetchedRequest.predicate=dP;
but app is crashing while fetching request.
Is there any other way to do it?
Please help me with this.
Any help is much appreciated.
To select objects which have any category from the given array
a simple predicate is sufficient:
NSPredicate(format: "catId IN %#", catArray)
Remark: Never use String(format:) to build predicates dynamically,
because almost surely the quoting and escaping will be wrong.
Use only NSPredicate(format:) and, if necessary, NSCompoundPredicate.
I'm trying to create a game and need to be able to save a number and retrieve it. I've found another tutorial on this but it is outdated and kept giving errors:
//To save highest score
var highestScore:Int = 20
NSUserDefaults.standardUserDefaults().setObject(highestScore,
forKey:"HighestScore")
NSUserDefaults.standardUserDefaults().synchronize()
//To get the saved score
var savedScore: Int =
NSUserDefaults.standardUserDefaults().objectForKey("HighestScore") as Int
println(savedScore)
More Details: It's to save a highscore if that helps (which I don't think it does).
Any help is welcome, Thanks.
NSUserDefaults.standardUserDefaults().setInteger(20, forKey: "HighestScore")
let valueOrZeroIfNotSet = NSUserDefaults.standardUserDefaults().integerForKey("HighestScore")
NSUserdefaults are a really useful tool, you can permenantly create mutable variables that can be read and written anywhere and anytime. Heres a brief explanation of how to use them.
let saves = NSUserdefaults.standardUserDefaults()
You need to declare a NSUserdefaults to begin, now this is where you will be storing data. Imagine it as a Bookshelf, right now its empty but you can fill it with all forms of information.
Now that we have our 'Bookshelf', we can start filling it with Books, these books can be everything such as Integers, and Strings.
If we want to store my name (Peter) in a 'book' on the shelf, we would first have to create the book and give it a name. The name of the book is called the "key". The key has to be a unique String. Because Im storing my name the key will be "myName". Now we know our key to write to, now lets fill the book with information (Which is my name).
saves.setString("Peter", forKey: "myName")
Now we've made a book in our bookshelf that stores our name.
We will probably want to read this information just in case we need it! We can access books from our bookshelf easily with:
saves.stringForKey("myName")
Now we did need the key (the books name) so we could find the right book of information.
Thats pretty much it for NSUserdefaults for you.
During dehydration I create a custom value:
def dehydrate(self, bundle):
bundle.data['custom_field'] = ["add lots of stuff and return an int"]
return bundle
that I would like to filter on.
/?format=json&custom_field__gt=0...
however I get an error that the "[custom_field] field has no 'attribute' for searching with."
Maybe I'm misunderstanding custom filters, but in both build_filters and apply_filters I can't seem to get access to my custom field to filter on it. On the examples I've seen, it seems like I'd have to redo all the work done in dehydrate in build_filters, e.g.
for all the items:
item['custom_field'] = ["add lots of stuff and return an int"]
filter on item and add to pk_list
orm_filters["pk__in"] = [i.pk for i in pk_list]
which seems wrong, as I'm doing the work twice. What am I missing?
The problem is that dehydration is "per object" by design, while filters are per object_list. That's why you will have to filter it manually and redo work in dehydration.
You can imagine it like this:
# Whole table
[obj, obj1, obj2, obj3, obj4, obj5, obj5]
# filter operations
[...]
# After filtering
[obj1, obj3, obj6]
# Returning
[dehydrate(obj), dehydrate(obj3), dehydrate(obj5)]
In addition you can imagine if you fetch by filtering and you get let say 100 objects. It would be quite inefficient to trigger dehydrate on whole table for instance 100000 records.
And maybe creating new column in model could be candidate solution if you plan to use a lot of filters, ordering etc. I guess its kind of statistic information in this field so if not new column then maybe django aggregation could ease your pain a little.
In order to retrieve a contact, having a cell phone number of 09362724853, I use following code:
$newSMS_contact = new Contact;
$newSMS_contact->retrieve_by_string_fields(array('phone_mobile'=>'09362724853'));
How about retrieving a contact having a cell phone number of 09362724853 OR 9362724853 OR +989362724853 with sugar internal functions?
This doesn't work:
$newSMS_contact = new Contact;
$newSMS_contact->retrieve_by_string_fields(array('phone_mobile'=>'09362724853', 'phone_mobile'=>'9362724853', 'phone_mobile'=>'+989362724853'));
The thing is that the function which you are trying to utilize was created for other goals. Since it fetches only one row from DB and fills a Bean with it, the Array of parameters will be turned into a string separated by AND operators. But you have completely different case.
I would suggest to use another approach, which is less convenient but more reliable:
$contact_bean = new Contact();
$contacts_list = $contact_bean->get_full_list(null, '(phone_mobile = "09362724853" OR phone_mobile = "9362724853" OR phone_mobile = "+989362724853")');
Eventually, you will have an array of beans.
Probably, for some modules, you will need to use table aliases for fields definition into SQL supplement.
If I were you, I'd have strict rules when the phone numbers are put in the system so you can be sure your phone numbers follow a certain format in the database. (Something like E.164: http://en.wikipedia.org/wiki/E.164) You can enforce the rules with a custom SugarField (or override one that exists) that has Javascript and Server-side validation.
This way, you won't have to worry about that logic in this piece of the code or anywhere else you want to deal with phone numbers.
I want to include child objects on an IQueryable list..
I want to include a child object on selected columns of some table type IQueryable list..
I tried like this:
IQueryable<Persons> persons = Context.Persons.Select(x=> new persons{Pkid=x.pkid, FirstName=x.FirstName}).AsQueryable();
persons= persons.Include("Address");
this include of child objects is not working..anyone please help...where I am doing wrong..
thanks alot...
Include doesn't work with projection. Moreover it is not needed. Just do this:
var query = context.Persons
.Select(x => new PersonDto
{
Id = x.pkid,
FirstName = x.FirstName,
Address = x.Address
});
Few points here:
No Include
Address accessed directly in projection, EF will handle this
I'm using PersonDto as target of projection. PersonDto has just Id, FirstName and Address.
You can project to custom type or anonymous type but you cannot project to entity type (the mapped type) - it doesn't work and it throws exception.
If you want to use mapped type you can't return only selected scalar columns - all columns will always be loaded. Only navigation properties can be loaded selectively. To overcome this people sometimes use Table splitting but that is something which works if you can divide your big entity into disjunct entities. In your scenario use just projection.
You cannot use Include() on a projection, try this:
Iquerable<Persons> persons = Context.Persons
.Include("Address")
.Select(x=> new persons{Pkid=x.pkid, FirstName=x.FirstName})
.AsQuerable();
Also you have a naming conflict, you project to a type persons and want to hold the results in an IQueryable named persons - one of them is wrong. Is there a reason you need the projection at all? You could just do
Iquerable<Persons> persons = Context.Persons.Include("Address");
First: Check if lazy loading is enabled or not. I experienced different results when it was enabled. I prefer lazy loading being disabled.
Second: Check this syntax:
result = (From person In context.Persons.Include("Address")).ToList();
P.S.: Useful EF Tips & Tricks : http://blogs.msdn.com/b/alexj/archive/2009/03/26/index-of-tips.aspx
UPDATE:
Include is not working, because your are using it on newly created objects, not the objects available in the context. you should use Include before creating new objects.
Check This:
result = (From person In context.Persons.Include("Address") Select New With {.FirstName = item.FirstName, .AddressValue = item.Address.Value}).ToList();