奇怪的字典排序 ios objective c
Strange dictionary sort ios objective c
我想做一种奇怪的字典排序。我有非唯一值和键并得到类似这样的东西
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];
}
}
一种旧方法是手动对数组进行排序,方法是在每次迭代中搜索最大值,当你找到最大值时,从另一个向量的最大数索引处获取名称并将其移动在新向量中...
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 长度的元素。
试试这个。
sortedArray = [yourArray sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
对数组进行排序后,使用以下方法删除重复项。
NSOrderedSet *orderedSet = [NSOrderedSet orderedSetWithArray: sortedArray];
NSArray *arrayWithoutDuplicates = [orderedSet array];
你的问题出在你的算法设计上,如果你在调试器中一次单步执行一行,你应该看到它做了什么以及哪里出错了。
我们不是来给你写代码的,但让我们看看我们是否可以通过算法的一步来帮助你按照自己的方式行事:
有用的事实:如果您在字典中查找一个键并且该键不存在,则 return 值将是 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
如果名称作为键存在,这将 return 当前关联值 - 在这种情况下为分数,如果没有匹配键,这将 return nil
。我们可以在单个 if
:
中对此进行测试
if (currentScore == nil // not seen user before, no high score
|| currentScore.integerValue < countInt) // seen user, countInt is greater
{
如果我们需要添加名称或更新其分数,上述条件将评估为真。添加和更新 key/value 对是相同的操作,所以我们只需要行:
highScores[nameString] = @(countInt); // add or update score for user
和一对大括号来终止 if
和 for
:
}
}
让我们看看我们有什么:
NSLog(@"Output: %@", highScores);
这输出:
Output: {
Jen = 6;
Jerry = 2;
Marge = 3;
Mark = 10;
}
这是朝着正确方向迈出的一步。 (注意:字典没有排序,NSLog
只是按排序顺序显示键。)
确保您了解其工作原理,复制代码并进行测试。然后尝试设计下一阶段的算法。
如果您遇到困难,可以提出一个新问题,展示您开发的算法和代码,有人可能会提供帮助。 如果你这样做,你应该在这个问题中包含一个 link,这样人们就可以看到历史(并且知道你不是试图通过多个问题来为你编写一个应用程序!)
HTH
我想做一种奇怪的字典排序。我有非唯一值和键并得到类似这样的东西
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];
}
}
一种旧方法是手动对数组进行排序,方法是在每次迭代中搜索最大值,当你找到最大值时,从另一个向量的最大数索引处获取名称并将其移动在新向量中...
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 长度的元素。
试试这个。
sortedArray = [yourArray sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
对数组进行排序后,使用以下方法删除重复项。
NSOrderedSet *orderedSet = [NSOrderedSet orderedSetWithArray: sortedArray];
NSArray *arrayWithoutDuplicates = [orderedSet array];
你的问题出在你的算法设计上,如果你在调试器中一次单步执行一行,你应该看到它做了什么以及哪里出错了。
我们不是来给你写代码的,但让我们看看我们是否可以通过算法的一步来帮助你按照自己的方式行事:
有用的事实:如果您在字典中查找一个键并且该键不存在,则 return 值将是 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
如果名称作为键存在,这将 return 当前关联值 - 在这种情况下为分数,如果没有匹配键,这将 return nil
。我们可以在单个 if
:
if (currentScore == nil // not seen user before, no high score
|| currentScore.integerValue < countInt) // seen user, countInt is greater
{
如果我们需要添加名称或更新其分数,上述条件将评估为真。添加和更新 key/value 对是相同的操作,所以我们只需要行:
highScores[nameString] = @(countInt); // add or update score for user
和一对大括号来终止 if
和 for
:
}
}
让我们看看我们有什么:
NSLog(@"Output: %@", highScores);
这输出:
Output: {
Jen = 6;
Jerry = 2;
Marge = 3;
Mark = 10;
}
这是朝着正确方向迈出的一步。 (注意:字典没有排序,NSLog
只是按排序顺序显示键。)
确保您了解其工作原理,复制代码并进行测试。然后尝试设计下一阶段的算法。
如果您遇到困难,可以提出一个新问题,展示您开发的算法和代码,有人可能会提供帮助。 如果你这样做,你应该在这个问题中包含一个 link,这样人们就可以看到历史(并且知道你不是试图通过多个问题来为你编写一个应用程序!)
HTH