[IOS 開發] Linq數組排序

來源:互聯網
上載者:User

[IOS 開發] Linq數組排序
Linq To Objective-C

 

原文地址:www.bkjia.com

Bringing a Linq-style fluent query API to Objective-C.

This project contains a collection of NSArray and NSDictionary methods that allow you to execute queries using a fluent syntax, inspired by Linq. In order to use Linq to Objective-C simply copy the NSArray+LinqExtensions.h, NSArray+LinqExtensions.m, NSDictionary+LinqExtensions.h and NSDictionary+LinqExtensions.m files into your project and import the header within any file where you wish to use the API.

Alternatively, you can include these files via CocoaPods.

As an example of the types of query this API makes possible, let's say you have an array of Person instances, each with a surname property. The following query will create a sorted, comma-separated list of the unique surnames from the array:

LINQSelector surnameSelector = ^id(id person){    return [person name];};LINQAccumulator csvAccumulator = ^id(id item, id aggregate) {    return [NSString stringWithFormat:@%@, %@, aggregate, item];};NSArray* surnamesList = [[[[people linq_select:surnameSelector]                                   linq_sort]                                   linq_distinct]                                   linq_aggregate:csvAccumulator];

For a detailed discussion of the history of Linq and why I implemented this API, see the related blog post.

Licence

The code within project is made available under the standard MIT licence, see the included licence file.

API Overview

NSArray methods:

  • linq_wherelinq_selectlinq_sortlinq_ofTypelinq_selectManylinq_distinctlinq_aggregatelinq_firstOrNillinq_lastOrNillinq_skiplinq_takelinq_anylinq_alllinq_groupBylinq_toDictionarylinq_countlinq_concatlinq_reverse

    NSDictionary methods:

    • linq_wherelinq_selectlinq_toArraylinq_anylinq_alllinq_countlinq_mergeNSArray methods

      This section provides a few brief examples of each of the API methods. A number of these examples use an array of Person instances:

      interface Person : NSObject@property (retain, nonatomic) NSString* name;@property (retain, nonatomic) NSNumber* age;@end
      linq_where
      - (NSArray*) linq_where:(LINQCondition)predicate;

      Filters a sequence of values based on a predicate.

      The following example uses the where method to find people who are 25:

      NSArray* peopleWhoAre25 = [input linq_where:^BOOL(id person) {    return [[person age] isEqualToNumber:@25];}];
      linq_select
      - (NSArray*) linq_select:(LINQSelector)transform;

      Projects each element of a sequence into a new form. Each element in the array is transformed by a 'selector' into a new form, which is then used to populate the output array.

      The following example uses a selector that returns the name of each Person instance. The output will be an array of NSString instances.

      NSArray* names = [input linq_select:^id(id person) {    return [person name];}];
      linq_sort
      - (NSArray*) linq_sort;- (NSArray*) linq_sort:(LINQSelector)keySelector;- (NSArray*) linq_sortDescending;- (NSArray*) linq_sortDescending:(LINQSelector)keySelector;

      Sorts the elements of an array, either via their 'natural' sort order, or via a keySelector.

      As an example of natural sort, the following sorts a collection of NSNumber instances:

      NSArray* input = @[@21, @34, @25];NSArray* sortedInput = [input linq_sort]; // 21, 25, 34

      In order to sort an array of Person instances, you can use the key selector:

      NSArray* sortedByName = [input linq_sort:^id(id person) {    return [person name];}];

      The accompanying 'descending' methods simply reverse the sort order:

      NSArray* input = @[@21, @34, @25];NSArray* sortedInput = [input linq_sort]; // 21, 25, 34NSArray* sortedInput = [input linq_sortDescending]; // 34, 25, 21
      linq_ofType
      - (NSArray*) linq_ofType:(Class)type;

      Filters the elements of an an array based on a specified type.

      In the following example a mixed array of NSString and NSNumber instances is filtered to return just the NSString instances:

      NSArray* mixed = @[@foo, @25, @bar, @33];NSArray* strings = [mixed linq_ofType:[NSString class]];
      linq_selectMany
      - (NSArray*) linq_selectMany:(LINQSelector)transform;

      Projects each element of a sequence to an NSArray and flattens the resulting sequences into one sequence.

      This is an interesting one! This is similar to the select method, however the selector must return an NSArray, with the select-many operation flattening the returned arrays into a single sequence.

      Here's a quick example:

      NSArray* data = @[@foo, bar, @fubar];NSArray* components = [data linq_selectMany:^id(id string) {    return [string componentsSeparatedByString:@, ];}];

      A more useful example might use select-many to return all the order-lines for an array of orders.

      linq_distinct
      - (NSArray*) linq_distinct;- (NSArray*) linq_distinct:(LINQSelector)keySelector;

      Returns distinct elements from a sequence. This simply takes an array of items, returning an array of the distinct (i.e. unique) values in source order.

      The no-arg version of this method uses the default method of comparing the given objects. The version that takes a key-selector allows you to specify the value to use for equality for each item.

      Here's an example that returns the distinct values from an array of strings:

      NSArray* names = @[@bill, @bob, @bob, @brian, @bob];NSArray* distinctNames = [names linq_distinct];// returns bill, bob and brian

      Here's a more complex example that uses the key selector to find people instances with distinct ages:

      NSArray* peopleWithUniqueAges = [input linq_distinct:^id(id person) {    return [person age];}];
      linq_aggregate
      - (id) linq_aggregate:(LINQAccumulator)accumulator;

      Applies an accumulator function over a sequence. This method transforms an array into a single value by applying an accumulator function to each successive element.

      Here's an example that creates a comma separated list from an array of strings:

      NSArray* names = @[@bill, @bob, @brian];id aggregate = [names linq_aggregate:^id(id item, id aggregate) {    return [NSString stringWithFormat:@%@, %@, aggregate, item];}];// returns bill, bob, brian

      Here's another example that returns the largest value from an array of numbers:

      NSArray* numbers = @[@22, @45, @33];id biggestNumber = [numbers linq_aggregate:^id(id item, id aggregate) {    return [item compare:aggregate] == NSOrderedDescending ? item : aggregate;}];// returns 45 
      linq_firstOrNil
      - (id) linq_firstOrNil;- (id) linq_firstOrNil:(LINQCondition)predicate;

      Returns the first element of an array, or nil if the array is empty.

      linq_lastOrNil
      - (id) linq_lastOrNil;

      Returns the last element of an array, or nil if the array is empty

      linq_skip
      - (NSArray*) linq_skip:(NSUInteger)count;

      Returns an array that skips the first 'n' elements of the source array, including the rest.

      linq_take
      - (NSArray*) linq_take:(NSUInteger)count;

      Returns an array that contains the first 'n' elements of the source array.

      linq_any
      - (BOOL) linq_any:(LINQCondition)condition;

      Tests whether any item in the array passes the given condition.

      As an example, you can check whether any number in an array is equal to 25:

      NSArray* input = @[@25, @44, @36];BOOL isAnyEqual = [input linq_any:^BOOL(id item) {        return [item isEqualToNumber:@25];    }];// returns YES
      linq_all
      - (BOOL) linq_all:(LINQCondition)condition;

      Tests whether all the items in the array pass the given condition.

      As an example, you can check whether all the numbers in an array are equal to 25:

      NSArray* input = @[@25, @44, @36];BOOL areAllEqual = [input linq_all:^BOOL(id item) {        return [item isEqualToNumber:@25];    }];// returns NO
      linq_groupBy
      - (NSDictionary*) linq_groupBy:(LINQSelector)groupKeySelector;

      Groups the items in an array returning a dictionary. The groupKeySelector is applied to each element in the array to determine which group it belongs to.

      The returned dictionary has the group values (as returned by the key selector) as its keys, with an NSArray for each value, containing all the items within that group.

      As an example, if you wanted to group a number of strings by their first letter, you could do the following:

      NSArray* input = @[@James, @Jim, @Bob];NSDictionary* groupedByFirstLetter = [input linq_groupBy:^id(id name) {   return [name substringToIndex:1];}];// the returned dictionary is as follows:// {//     J = (James, Jim);//     B = (Bob);// }
      linq_toDictionary
      - (NSDictionary*) linq_toDictionaryWithKeySelector:(LINQSelector)keySelector;- (NSDictionary*) linq_toDictionaryWithKeySelector:(LINQSelector)keySelector valueSelector:(LINQSelector)valueSelector;

      Transforms the source array into a dictionary by applying the given keySelector and (optional) valueSelector to each item in the array. If you use the toDictionaryWithKeySelector: method, or the toDictionaryWithKeySelector:valueSelector: method with a nil valueSelector, the value for each dictionary item is simply the item from the source array.

      As an example, the following code takes an array of names, creating a dictionary where the key is the first letter of each name and the value is the name (in lower case).

      NSArray* input = @[@Frank, @Jim, @Bob];NSDictionary* dictionary = [input linq_toDictionaryWithKeySelector:^id(id item) {    return [item substringToIndex:1];} valueSelector:^id(id item) {    return [item lowercaseString];}];// result:// (//    F = frank;//    J = jim;//    B = bob;// )

      Whereas in the following there is no value selector, so the strings from the source array are used directly.

      NSArray* input = @[@Frank, @Jim, @Bob];NSDictionary* dictionary = [input linq_toDictionaryWithKeySelector:^id(id item) {    return [item substringToIndex:1];}];// result:// (//    F = Frank;//    J = Jim;//    B = Bob;// )
      linq_count
      - (NSUInteger) linq_count:(LINQCondition)condition;

      Counts the number of elements in an array that pass a given condition.

      As an example, you can check how many numbers equal a certain value:

      NSArray* input = @[@25, @35, @25];NSUInteger numbersEqualTo25 = [input linq_count:^BOOL(id item) {    return [item isEqualToNumber:@25];}];// returns 2
      linq_concat
      - (NSArray*) linq_concat:(NSArray*)array;

      Returns an array which is the result of concatonating the given array to the end of this array.

      linq_reverse
      - (NSArray*) linq_reverse;

      Returns an array that has the same elements as the source but in reverse order.

      NSDictionary methods

      This section provides a few brief examples of each of the API methods.

      linq_where
      - (NSDictionary*) linq_where:(LINQKeyValueCondition)predicate;

      Filters a dictionary based on a predicate.

      The following example uses filters a dictionary to remove any keys that are equal to their value.

      NSDictionary* result = [input linq_where:^BOOL(id key, id value) {   return [key isEqual:value];}];
      linq_select
      - (NSDictionary*) linq_select:(LINQKeyValueConditionKeyValueSelector)selector;

      Projects each key-value pair in a dictionary into a new form. Each key-value pair is transformed by a 'selector' into a new form, which is then used to populate the values of the output dictionary.

      The following example takes a dictionary which has string values, returning a new dictionary where each value is the first character of the source string.

      NSDictionary* result = [input linq_select:^id(id key, id value) {    return [value substringToIndex:1];}];
      linq_toArray
      - (NSArray*) linq_toArray:(LINQKeyValueSelector)selector;

      Projects each key-value pair in a dictionary into a new form, which is used to populate the output array.

      The following example takes a dictionary which has string values, returning an array which concatenates the key and value for each item in the dictionary.

      NSDictionary* input = @{@A : @Apple, @B : @Banana, @C : @Carrot};NSArray* result = [input linq_toArray:^id(id key, id value) {    return [NSString stringWithFormat:@%@, %@, key, value];}];// result:// (//    A, Apple,//    B, Banana,//    C, Carrot// )
      linq_any
      - (BOOL) linq_any:(LINQKeyValueCondition)condition;

      Tests whether any key-value pair in the dictionary passes the given condition.

      As an example, you can check whether value contains the letter 'n':

      NSDictionary* input = @{@a : @apple, @b : @banana, @c : @bat};BOOL anyValuesHaveTheLetterN = [input linq_any:^BOOL(id key, id value) {    return [value rangeOfString:@n].length != 0;}];// returns YES
      linq_all
      - (BOOL) linq_all:(LINQKeyValueCondition)condition;

      Tests whether all the key-value pairs in the dictionary pass the given condition.

      As an example, you can check whether all values contains the letter 'a', or use the key component of the condition to see if each value contains the string key:

      NSDictionary* input = @{@a : @apple, @b : @banana, @c : @bat};BOOL allValuesHaveTheLetterA = [input linq_all:^BOOL(id key, id value) {    return [value rangeOfString:@a].length != 0;}];// returns YESBOOL allValuesContainKey = [input linq_all:^BOOL(id key, id value) {    return [value rangeOfString:key].length != 0;}];// returns NO - the value 'bat' does not contain the letter it is keyed with 'c'
      linq_count
      - (NSUInteger) linq_count:(LINQKeyValueCondition)condition;

      Counts the number of key-value pairs that satisfy the given condition.

      The following example counts how many dictionary values contain the key:

      NSDictionary* input = @{@a : @apple, @b : @banana, @c : @bat};NSUInteger valuesThatContainKey = [input linq_count:^BOOL(id key, id value) {    return [value rangeOfString:key].length != 0;}];// returns 2 - bat does not contain the key c
      linq_merge
      - (NSDictionary*) linq_merge:(NSDictionary*)dic;

      Merges the contents of this dictionary with the given dictionary. For any duplicates, the value from the source dictionary will be used.

      The following example merges a pair of dictionaries

      NSDictionary* input = @{@a : @apple, @b : @banana, @c : @cat};NSDictionary* result = [input linq_merge:@{@d : @dog, @e : @elephant}];// result:// (//    a = apple;//    b = banana;//    c = cat;//    d = dog;//    e = elephant;// )

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.