2012-02-10 2 views
1

Я привык работать в C#, используя расширения linq (list.select (...). Where (...) ext), и мне было интересно, если в Objective-C был способ сделать то же самое. Это избавит меня от создания ряда довольно сложных запросов с использованием Core Data, что отлично подходит для некоторых вещей, но, возможно, не подходит для сложных запросов (или, может быть, я просто не проинформирован).Количество элементов в NSArray, где (....)

Есть ли какой-то эквивалент для linq в Objective-C/Core Data?

EDIT: В частности, я хотел бы подсчитать количество элементов, соответствующих определенным критериям. Скажем, у моей модели есть поле, называемое датой. Я пытаюсь выбрать различные даты, а затем рассчитать, сколько из них есть. В SQL это будет похоже на группу и агрегат COUNT.

+0

Вместо того, лавируя на «EDIT:» Вы должны просто переписать свой вопрос более конкретно. – benzado

+0

Я понимаю, о чем вы говорите, но я уже получил некоторые ответы, и я хотел, чтобы это было ясно для тех, кто изменил вопрос. – mtmurdock

ответ

1

Ваш вопрос идет от очень общего («linq эквивалент?») К очень конкретному (вычисляет подсчет по дате). Я просто отвечу на ваш конкретный вопрос.

К сожалению, NSArray не имеет встроенную карту или выберите метод, но он предлагает NSCountedSet, который вычислит, что вы хотите:

NSCountedSet *dateSet = [NSCountedSet set]; 
for (id thing in array) { 
    [dateSet addObject:[thing date]]; 
} 
for (NSDate *date in dateSet) { 
    NSLog(@"There are %d instances of date %@", [dateSet countForObject:date], date); 
} 
+0

Это выглядит очень многообещающим. Я попробую. Предполагается, что 'uniqueDates' должен быть' dateSet' в вашем примере? – mtmurdock

+0

Ваш был самым простым и элегантным (хотя я уверен, что другие будут работать). Отлично сработано. Благодаря! – mtmurdock

+0

'uniqueDates' должен был быть' dateSet'; Должно быть, я решил изменить имя во время написания кода.Рад, что ты все это понял. – benzado

0

Здесь было что-то писал с сближается filtering NSArray into a new NSArray in objective-c

Во всяком случае AFAIK у вас нет какой-то LINQ в Objective-C, но у вас есть. Массивы и блоки. Блоки - это функции. Поэтому вы можете фильтровать что угодно.

0

Конечно, Кора данных имеет множество функций, чтобы сделать сложные запросы: В примере, чтобы получить сумму элементов, у вас есть два основных способа:

первый - получить данные в NSSet или NSArray и использовать @sum оператор:

//assume that `childs` are NSArray of your child entities and ammount is attribute to sum, and has attributes start (date) and completion (integer) 

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
NSEntityDescription *entity = [NSEntityDescription entityForName:@"child" inManagedObjectContext:managedObjectContext]; 
[fetchRequest setEntity:entity]; 

NSPredicate *predicate =[NSPredicate predicateWithFormat:@"(start <= %@) and (completion < 100)", dzis]; 
[fetchRequest setPredicate:predicate]; 

NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:@"Root"]; 
NSError *error = nil; 
if ([afetchedResultsController performFetch:&error]) { 
    NSArray *childs = afetchedResultsController.fetchedObjects; 
    NSNumber *sum=[childs valueForKeyPath:"@sum.ammount"]; 
} 

второй использует конкретные выборки for specific value с добавлением NSExpressionDescription с суммой. Этот способ труднее, но лучше для больших db

+0

Хорошо, это похоже на то, чтобы двигаться в правильном направлении, но как я могу считать разные даты? – mtmurdock

+0

В первом примере это очень просто, вы должны получить подходящую часть данных, используя NSPredicate. Я просто расширяю свой пример. –

0

Предположим, если у вас есть массив из ваших объектов модели , вы могли бы с этим предложением,

NSArray *distintDatesArray = [array valueForKeyPath:@"@distinctUnionOfObjects.date"]; 

    for (NSDate *date in distintDatesArray) 
    { 
     NSLog (@"Date :%@ ,count : %d",date,[[array filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"date = %@",date]] count]); 
    } 

Это будет иметь тот же эффект, что и группа по запросу.

+0

Мне не нужно количество отдельных дат, мне нужно подсчет КАЖДОЙ отдельной даты. Я хочу знать, сколько записей имеет одну и ту же дату, для всех разных дат. – mtmurdock

1

Изменить предикат, и ключи «Date» с реквизитом

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
NSEntityDescription *entity = [NSEntityDescription entityForName:@"child" inManagedObjectContext:self.managedObjectContext]; 
[fetchRequest setEntity:entity]; 
[fetchRequest setReturnsDistinctResults:YES]; 
[fetchRequest setPropertiesToFetch:[NSArray arrayWithObject:@"Date"]]; 
NSPredicate *predicate =[NSPredicate predicateWithFormat:@"(start <= %@) and (completion < 100)",sda ]; 
[fetchRequest setPredicate:predicate]; 
int c = [self.managedObjectContext countForFetchRequest:fetchRequest error:nil]; 
+0

Хорошо, это выглядит лучше. Поэтому мне пришлось бы называть 'countForFetchRequest: error:' для каждой отдельной даты? Все еще не идеально ... Может ли это быть изменено, чтобы отменить список пар ключ-значение, где Date - это ключ, а count - значение? – mtmurdock