【问题标题】:Strange dictionary sort ios objective c奇怪的字典排序ios目标c
【发布时间】:2016-02-29 15:28:41
【问题描述】:

我想做一种奇怪的字典排序。我有非唯一的值和键并得到类似的东西

 NSArray *counts = [@"1",@"2",@"2",@"3",@"6",@"10"];
 NSArray *names =[@"Jerry",@"Marge",@"Jerry",@"Marge",@"Jen",@"Mark"];

我想要的输出是一个具有唯一名称的降序列表。我不希望输出数组中同一个人的值较低。输出应该是。

sortedNames=[@"Mark",@"Jen",@"Marge",@"Jerry"]
sortedCounts=[@"10",@"6",@"3",@"2"];

我非常感谢您对此的帮助。

NSMutableArray *userNameArray = [[NSMutableArray alloc] init];
NSMutableArray *countArray = [[NSMutableArray alloc] init];
for (NSDictionary *dict in bigDick) {
    NSString *nameString =[dict objectForKey:@"Name"];
    NSString *countString =[dict objectForKey:@"Count"];
    NSInteger countInt = [countString integerValue];
    NSNumber *countNumber =[NSNumber numberWithInt:countInt];
    [userNameArray addObject:nameString];
    [countArray addObject:countNumber];
}
NSArray *namesAscending =[[userNameArray reverseObjectEnumerator]allObjects];
NSArray *countsAscending=[[countArray reverseObjectEnumerator]allObjects];
// Put the two arrays into a dictionary as keys and values
NSDictionary *dictionary = [NSDictionary dictionaryWithObjects:countsAscending forKeys:namesAscending];
// Sort the first array
NSArray *sortedCountArray = [[dictionary allValues] sortedArrayUsingSelector:@selector(compare:)];
// Sort the second array based on the sorted first array
//  NSArray *sortedNameArray= [dictionary objectsForKeys:sortedCountArray notFoundMarker:[NSNull null]];
NSMutableArray *nameArray =[[NSMutableArray alloc] init];
for (int i=1; i<sortedCountArray.count; i++) {

    NSString *name = [dictionary allKeysForObject:sortedCountArray[i]];
    if (sortedCountArray[i]!=sortedCountArray[i-1]) {
        [nameArray addObject:name];

    }
}

【问题讨论】:

  • 为什么是字典?为什么不是自定义对象数组?你写过滤器了吗?这个问题太笼统了……
  • 先排序,然后删除重复项。
  • 你有没有尝试过?如果是这样,您遇到了什么问题?

标签: ios objective-c sorting nsarray nsdictionary


【解决方案1】:

一种旧方法是使用数字手动对数组进行排序,方法是在每个迭代中搜索最大值,当你找到最大值时,从最大数字索引处的另一个向量中获取名称并将其移动到新的矢量...

max = counts[0];
counter = 0;
for (int i=0;i<counts.count;i++)
  {
   temp = counts[i];
   if (max<temp)
   max = temp;
   counter = i;
   }

   [new_names addObject: [names objectAtIndex:counter]];
   [new_numbers addObject: max];
   [numbers removeObjectAtIndex: counter];
   [names removeObjectAtIndex:counter];

试试这样的。如果你这样做,它应该可以工作。 重要的!不要从数组中删除你计算为 for 长度的元素。

【讨论】:

    【解决方案2】:

    您的问题在于您的算法设计,如果您在调试器中一次执行一行,您应该会看到它做了什么以及哪里出错了。

    我们不是来给你写代码的,但让我们看看我们是否可以通过算法的一步来帮助你:

    有用的事实:如果您在字典中查找一个键并且该键不存在,则返回值将是 nil

    据此:您可以使用字典来跟踪您所见过的与迄今为止得分最高的名称配对的名称。你得到一个名字,分数对,在字典中查找这个名字——如果你得到nil它是一个新的名字和一个新的高分。如果不是nil是目前已知的高分,可以对比更新。

    这是一个粗略的算法,让我们尝试一下。在开始之前,我们先定义一些常量,而不是在任何地方使用文字字符串作为键。这样做的好处是我们不会输入错误的字符串,如果我们输入错误的常量名称,编译器会发现。这些可以在文件级别或方法中定义:

    const NSString *kName = @"Name";
    const NSString *kCount = @"Count";
    

    现在来看代码,在某个方法中,我们需要一个字典:

    NSMutableDictionary *highScores = [NSMutableDictionary new]; // a single dictionary rather than your two arrays
    

    现在像以前一样开始你的循环:

    for (NSDictionary *dict in bigDict)                  // same loop as your code
    {
    

    并像以前一样提取两个值:

       NSString *nameString = dict[kName];               // same as your code, but using modern syntax
       NSInteger countInt = [dict[kCount] integerValue]; // condense two lines of your code into one
    

    现在我们可以在字典中查找名字了:

       NSNumber *currentScore = highScores[nameString];  // get current high score for user, if any
    

    如果名称作为键存在,这将返回当前关联的值 - 在这种情况下为分数,如果没有匹配的键,则返回 nil。我们可以在单个 if 中对此进行测试:

       if (currentScore == nil                           // not seen user before, no high score
           || currentScore.integerValue < countInt)      // seen user, countInt is greater
       {
    

    如果我们需要添加名称或更新其分数,上述条件将评估为真。添加和更新键/值对是相同的操作,所以我们只需要这行:

          highScores[nameString] = @(countInt);          // add or update score for user
    

    还有几个大括号来终止iffor

       }
    }
    

    让我们看看我们有什么:

    NSLog(@"Output: %@", highScores);
    

    这个输出:

    Output: {
        Jen = 6;
        Jerry = 2;
        Marge = 3;
        Mark = 10;
    }
    

    这是朝着正确方向迈出的一步。 (注意:字典没有排序,NSLog 只是按排序顺序显示键。

    确保您了解其工作原理,复制代码并进行测试。然后尝试设计算法的下一个阶段。

    如果您遇到困难,您可以提出一个新问题,展示您开发的算法和代码,有人可能会提供帮助。 如果您这样做,您应该包含一个指向此问题的链接,以便人们可以查看历史记录(并且知道您不是试图通过多个问题为您编写应用程序!)

    HTH

    【讨论】:

      【解决方案3】:

      试试这个。

      sortedArray = [yourArray sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
      

      对数组进行排序后,使用以下方法删除重复项。

      NSOrderedSet *orderedSet = [NSOrderedSet orderedSetWithArray: sortedArray];
      NSArray *arrayWithoutDuplicates = [orderedSet array];
      

      【讨论】:

      • 发送到 NSNumber 实例的无法识别的选择器这是编译器通常会告诉你的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多