How to compare the elements of NSArray in NSMutableDictionary?

為{幸葍}努か 提交于 2019-12-06 12:54:38

问题


My NSMutableDictionary contains four NSArrays with their respective keys. These NSArrays are of size 2 and contain 2D coordinates. I want to get the most common coordinate among them. For example, If a coordinate is common to three arrays, it would be my first choice. How can I find that any coordinate is common to at least two arrays?


回答1:


Basically you want to find the pair of coordinates that has max occurences. So you can create an array of all coordinates and find its mode.

    NSMutableArray *allCoordinates = [NSMutableArray new];
    [dictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
    if ([key isEqualToString:@"arrayKey1"] || [key isEqualToString:@"arrayKey2"]) {
        NSArray *coordinates = (NSArray *)obj;
        [coordinates enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
            [allCoordinates addObject:coordinates];
        }];
    }
    }];

Now, U need to write a custom method to find mode of an array of coordinates (with an additional condition of frequency being >=3).




回答2:


This is a working example. I'm assuming that your dictionary looks like coordinatesDict.

NSDictionary *coordinatesDict = @{@"first": @[@11.58, @40.20], @"second": @[@12.12, @100.12], @"third": @[@11.58, @40.20], @"fourth": @[@13.2, @14.5]};

NSCountedSet *coordinates = [NSCountedSet setWithArray:[coordinatesDict allValues]];

for (NSArray *coordinateArray in coordinates) {

    NSUInteger coordinateCount = [coordinates countForObject:coordinateArray];
    NSLog(@"Array %@ is included %lu times", coordinateArray, (unsigned long)coordinateCount);

    if (coordinateCount >= 2) {
        // You found your best coordinate
    }
}



回答3:


Here is some code that should work, using NSCountedSet.
In a few words: I use a NSCountedSet that will work as a NSSet keeping also the numbers of occurrences (duplicates times).
Then, I create a NSArray sorting the values descending according to the number of occurrences.
I wrote explicitly the "count1/count2" comparison in case you want to apply a different value if the number of occurrences is the same.

NSDictionary *allData = @{@"Key1: %@":@[@(0.0), @(0.1)],
                          @"Key2: %@":@[@(0.1), @(0.1)],
                          @"Key3: %@":@[@(0.2), @(0.1)],
                          @"Key4: %@":@[@(0.1), @(0.1)]};

NSCountedSet *countedSet = [[NSCountedSet alloc] initWithArray:[allData allValues]];

for (NSArray *array in countedSet)
    NSLog(@"For %@ counted %@ time(s)", array, @([countedSet countForObject:array]));

NSArray *sortedCountedSetArray = [[countedSet allObjects] sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2)
{
    NSUInteger count1 = [countedSet countForObject:obj1];
    NSUInteger count2 = [countedSet countForObject:obj2];
    if (count1 < count2)
        return NSOrderedDescending;
    if (count1 > count2)
        return NSOrderedAscending;
    else
        return NSOrderedSame; //May want to do additionaly thing (for example if coordinate is closer to actual position, etc.)
}];
NSLog(@"sortedCountedSetArray: %@", sortedCountedSetArray);

NSArray *bestOption = [sortedCountedSetArray firstObject]; //Coordinates the most "popular"
NSLog(@"BestOption: %@", bestOption);

The outputs are:

> For (
    "0.1",
    "0.1"
) counted 2 time(s)
> For (
    "0.2",
    "0.1"
) counted 1 time(s)
> For (
    0,
    "0.1"
) counted 1 time(s)
> sortedCountedSetArray: (
        (
        "0.1",
        "0.1"
    ),
        (
        "0.2",
        "0.1"
    ),
        (
        0,
        "0.1"
    )
)
> BestOption: (
    "0.1",
    "0.1"
)


来源:https://stackoverflow.com/questions/29096448/how-to-compare-the-elements-of-nsarray-in-nsmutabledictionary

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!