如何在Objective-C中根据一个对象在另一个数组中的顺序对一个数组进行排序?

时间:2019-04-22 13:33:51

标签: ios objective-c

我有按用户排序的列表。然后我再次从服务器获取列表。
有些元素可能会被删除或添加。 我想基于前一个数组的排序对新数组进行排序,然后添加新元素。

示例
oldElementList:[1、4、2、8] --->用户设置此顺序
newElementList:[1、4、3、8]

我想要的输出是:[1、4、8、3]

实际上元素不是数字,而是对象。当从服务器获取它们时,它们的某些属性值可能已更改。

我的答案:

for (ElementModel *oldElement in oldElementList) {
            for (ElementModel * newElement in newElementList) {
                if ([newElement.number isEqualToString: oldElement.number]) {
                    [sortedArray addObject: newElement];
                    [newElementList removeObject: newElement];

                    break;
                }
            }
        }

        for (ElementModel *newElement in newElementList) {
            [sortedArray addObject: newElement];
        }

我认为我的答案还不错,我想使其性能或其他我未考虑的方面更好。

1 个答案:

答案 0 :(得分:1)

哪种排序算法最合适取决于您的数据,例如:
-要排序的数据集是否很大(只有这样,复杂的算法才能奏效)?
-要排序的数据集是完全随机的还是预先排序的?
根据您的描述,在我看来您有一个很大的数据集(否则,提供正确结果的任何算法都可能会很好,包括您自己的复杂度为O(n ^ 2)的算法),并且已对其进行了预排序,即仅是一些添加和删除(否则,保持原始排序可能不是那么重要)。
如果是这样,那么下面的算法(抱歉,它在Swift中,但是可以肯定地很容易转换为Obj-C):

let old = [1, 4, 2, 7, 8]
let new = [1, 4, 3, 8, 2]

var oldIndexed: [Int: Int] = [:]
for i in 0 ..< old.count {
    oldIndexed[old[i]] = i
}
var newIndexed: [Int: Int] = [:]
for i in 0 ..< new.count {
    newIndexed[new[i]] = oldIndexed[new[i]] ?? old.count
}
var resultArray: [(Int, Int)] = []
for (key, value) in newIndexed {
    resultArray.append((key, value))
}
resultArray = resultArray.sorted { (first, second) -> Bool in
    first.1 < second.1
}
let result = resultArray.map{ $0.0 } // Here: [1, 4, 2, 8, 3]

这个想法是给旧的数据元素一个索引,而每个新的数据元素都具有相同的索引。这是通过使用字典来完成的,因为在那里每个元素都可以通过其O(1)中的键进行访问。新元素将获得更大的索引(这也可以是一个使它更清晰的计数器)。然后,新字典将转换回数组,然后按其索引排序。最终,索引被删除,结果准备就绪。
我猜想,由于算法是在标准库中实现的,因此该算法的复杂性取决于应该是最佳的排序函数。

编辑:

我很长一段时间都没有在Obj-C中编程,但再次尝试只是为了好玩:

NSArray *old = @[@1, @4, @2, @7, @8];
NSArray *new = @[@1, @4, @3, @8, @2];

NSMutableDictionary *oldIndexed = [[NSMutableDictionary alloc] init];
for (int i = 0; i < old.count; i++) {
    [oldIndexed setValue:[NSNumber numberWithInt: i] forKey: old[i]];
}

NSMutableDictionary *newIndexed = [[NSMutableDictionary alloc] init];
long counter = old.count;
for (int i = 0; i < old.count; i++) {
    NSNumber *oldIndexOfNewValue = oldIndexed[new[i]];
    NSNumber *newIndex;
    if (oldIndexOfNewValue != nil) {
        newIndex = oldIndexOfNewValue;
    } else {
        newIndex = [NSNumber numberWithLong: counter];
        counter++;
    }
    [newIndexed setValue: newIndex forKey: new[i]];
}

NSMutableArray *resultArray = [[NSMutableArray alloc] init];
NSArray *allKeysInNewIndexed = newIndexed.allKeys;
for (int i = 0; i < allKeysInNewIndexed.count; i++) {
    NSNumber *nextKey = allKeysInNewIndexed[i];
    NSArray *nextPair = @[nextKey, newIndexed[nextKey]];
    [resultArray addObject: nextPair];
}

NSArray *sortedResultArray;
sortedResultArray = [resultArray sortedArrayUsingComparator: ^NSComparisonResult(NSArray *first, NSArray *second) {
    NSNumber *firstIndex = first[1];
    NSNumber *secondIndex = second[1];
    return [firstIndex compare: secondIndex];
}];

NSMutableArray * result = [[NSMutableArray alloc] init];
for (int i = 0; i < sortedResultArray.count; i++) {
    [result addObject: sortedResultArray[i][0]];
}
相关问题