I would like to move the index 0 to end of array using NSPredicate.
I am using Core Data and I having an entity called Link that is have an attribute called orderingLink which is Integer 64 type.
I've tried to use this follow code and i've expected to move the index 0 to end of array.
open func fetchLinkRequest(_ links: [Links]? = nil) -> NSFetchRequest<NSFetchRequestResult> {
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: T.entityName)
let sort1 = NSSortDescriptor(key: "orderingLink", ascending: true)
fetchRequest.sortDescriptors = [sort1]
var predicates = [NSPredicate]()
predicates.append(NSPredicate(format: "orderingLink != 0 ", argumentArray: [links]))
fetchRequest.predicate = NSCompoundPredicate(type: NSCompoundPredicate.LogicalType.and, subpredicates: predicates)
return fetchRequest
Although, this code don't show the index 0 in array, and this was my latest progress in order to move the index 0 to end of array.
Please, help me how to solve this problem.
Thank You.
The answer to this is "You can't." Predicates let you sort or filter arrays or databases, but not modify them.
Related
I'm not able to figure out how to sort results from CoreData based on the number of matching relationships.
Concrete situation:
I have Recipe(s) that have one or more RecipeIngredient(s). I have a search interface where I can select multiple Ingredient(s) and want to get back Recipe(s) ordered by how many RecipeIngredient(s) match my selection. Basically I want to find the recipes with the highest number of matching ingredients.
CoreData schema:
Here is what I've done until now, (sort descriptor is just a default until I figure out how to handle this):
func searchRecipes(
searchRequest: RecipeSearchRequest
) -> [CDRecipe] {
let fetchRequest: NSFetchRequest<CDRecipe> = CDRecipe.fetchRequest()
var predicates: [NSPredicate] = []
if searchRequest.searchString != "" {
predicates.append(NSPredicate(format: "title CONTAINS %#", searchRequest.searchString.lowercased()))
}
if searchRequest.savedOnly {
predicates.append(NSPredicate(format: "saved == %#", "true"))
}
// HERE
if !searchRequest.includedIngredientIDs.isEmpty {
predicates.append(NSPredicate(format: "ANY ingredients.ingredient.identifier IN %#", searchRequest.includedIngredientIDs))
}
fetchRequest.predicate = NSCompoundPredicate(type: .and, subpredicates: predicates)
let sortDescriptor = NSSortDescriptor(keyPath: \CDRecipe.title, ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
fetchRequest.fetchLimit = searchRequest.limit
do {
let recipes = try coreDataStack.managedObjectContext.fetch(fetchRequest)
return recipes
} catch {
print(error.localizedDescription)
return []
}
}
I have also considered pulling all the recipes in my database and doing this sorting in memory. However I have 10K+ recipes and will have more in the future so doing this will would be highly inefficient.
Currently we have a database of multiple values for r,g,b, split into own attributes. ex:
r = type float
g = type float
b = type float
There will be multiple values for each r, g, and b attribute.
After getting a float from an outside source, we want to search the database to return the attribute with the closest number to that float. (ex. for r, if we get a value of 199, the r value with the closest value to 199 will be returned).
I know there are predicates that can be used like: "text CONTAINS[c] %#" but I didn't see any predicates for 'closest value'.
You can use NSSortDescriptor(key: "name_key", ascending: true) with your request.
let request1 = NSFetchRequest<NSFetchRequestResult>() // use correct constructor
let sortDescriptor = NSSortDescriptor(key: "name_key", ascending: true)
let sortDescriptors = [sortDescriptor]
request1.sortDescriptors = sortDescriptors
let predicate1 = NSPredicate(format: "text < %#", value)
request1.predicate = predicate1
// use this request1 to fetch from core data
let request2 = NSFetchRequest<NSFetchRequestResult>() // use correct constructor
request2.sortDescriptors = sortDescriptors
let predicate2 = NSPredicate(format: "text > %#", value)
request2.predicate = predicate2
// use this requst2 to fetch from core data
Then you can use predicate twice:
First time with format text < %# and use last item of the array.
and
Second time with format text > %# and use the first item of the array.
compare the difference of your first and last items from both iterations with your given value and see whose difference is smaller. That will be closest value.
If you don't know how to fetch data from core data you can follow Fetching Objects
Getting started with core data
I have two simple Entities:
Part {
#NSManaged var states: Set<PartState>
}
PartState {
#NSManaged var date: Date
#NSManaged var state: Int
}
I want to fetch those entities from Part, that newest PartState has state == 1.
I've tried to create NSPredicate:
NSPredicate(format: "SUBQUERY(states, $s, $s.date == max($s.date) AND $s.state == 1).#count > 0")
It looks like max($.date) checks all existing PartState entities, not just those belonging to a given Part and always returns 1 or 0 results.
NSPredicate(format: "ANY (states.state == 1 AND states.date == states.#max.date)")
Fails with: Unable to parse the format string...
NSPredicate(format: "ANY states.state == 1 AND ANY states.date == states.#max.date")
Returns all entities that have ever had state == 1 (which is what I would expect).
The only other solution that comes to my mind, is to have newestState property in Part but I still looking for some NSPredicate-based way.
You can fetch latest entry based on date using sort Descriptor
and apply predicate to fetch which has state == 1
let fetchRequest = NSFetchRequest<Part>.init(entityName: "Part")
fetchRequest.sortDescriptors = [NSSortDescriptor.init(key: "states.date", ascending: false)]
let predicate = NSPredicate.init(format: "states.state = %#","1")
When using a NSPredicate, I'm trying to search all objects (strings) contained within an array. The code sample below works but the predicate only collects the object in the first index only?? The NSPredicate is used for a CKQueryOperation.
Each Record has a value for a key named Category.
let array: [String] = ["Education", "Sport", "TV and Film"]
// select all records
//let predicate = NSPredicate(format: "Category = %#", category )
let predicate = NSPredicate (format: "Category == %#", argumentArray: array)
let query = CKQuery(recordType: "quizRecord", predicate: predicate)
// get just one value only
let operation = CKQueryOperation(query: query)
//code works but only queries Records with the Category for "Education"
Try replacing:
"Category == %#"
With:
"Category IN %#"
I was having the same issue as Peter Wiley. The solution I found was a mash up of Danny Bravo's solution and comment on that solution.
let arrayPredicate = NSPredicate(format: "Name IN %#", argumentArray: [names])
To get multiple results I needed to use both the keyword "IN" in the format and wrap my argumentArray with [].
Am Rewriting my existing objective c code(ios) to swift and now am facing some issues with Coredata NSPredicate in swift as there is some many to one relationships and vice-versa.. am using the following code,
let fetchRequest = NSFetchRequest(entityName: "TUMessage")
let sortSequence = NSSortDescriptor(key: "sequence", ascending: true)
let sortTime = NSSortDescriptor(key: "epoch_time", ascending: true)
var filterPredicate:NSPredicate = NSPredicate(format:"thread == [c] %#",contact.threads.anyObject())
 fetchRequest.predicate = filterPredicate
var sortDescriptor:NSArray = NSArray(objects: sortTime,sortSequence)
fetchRequest.sortDescriptors = sortDescriptor
fetchRequest.fetchBatchSize = 50
return fetchRequest
where "TUMessage" is the table we need to fetch data from, "sequence" for sorting the fetched result, "thread == [c] %#" is a relationship of message table (many to one since each contact have multiple thread) ,
and contact.threads.anyObject() is the predicate which am trying to add.Unfortunately am getting the following error
type anyobject? does not confirm to protocol, CVarArgType
Any help would be appreciated..
Thank you
You need to unwrap it and cast to the specific class
contact.threads.anyObject()! as MYClass