Finding out NSArray/NSMutableArray changes' indices

前端 未结 3 1390
陌清茗
陌清茗 2021-01-12 14:44

I have a NSMutableArray oldArray. Now, at one point, this NSMutableArray object gets updated with another NSMutableArray,

相关标签:
3条回答
  • 2021-01-12 15:02
    1. addedArray = newArray ∖ (newArray ∩ oldArray)

             = newArray ∖ ({@"a",@"c",@"d",@"e",@"f",@"h"} ∩ {@"a",@"b",@"d",@"e",@"g"}) 
             = newArray ∖ {@"a",@"d",@"e"}            
             = {@"a",@"c",@"d",@"e",@"f",@"h"} ∖ {@"a",@"d",@"e"}
             = {@"c",@"f",@"h"}             
      
    2. removedArray = oldArray ∖ (oldArray ∩ newArray)

               = oldArray ∖ ({@"a",@"b",@"d",@"e",@"g"} ∩ {@"a",@"c",@"d",@"e",@"f",@"h"})
               = oldArray ∖ {@"a",@"d",@"e"}
               = {@"a",@"b",@"d",@"e",@"g"} ∖ {@"a",@"d",@"e"}
               = {@"b",@"g"}
      

    To find intersections of array, you can view the following SO post: Finding Intersection of NSMutableArrays

    0 讨论(0)
  • 2021-01-12 15:05

    I have tried iterating through the old and the new arrays using loops and if conditions, but is it getting really messy and buggy.

    This is not a simple problem. First, note that it may have multiple solutions:

    a b c d
    b c d e
    

    both (a={0, 1, 2, 3}, r={0, 1, 2, 3}) and (a={3}, r={0}) are valid solutions. What you are probably looking for is a minimal solution.

    One way to get a minimal solution is by finding the Longest Common Subsequence (LCS) of the two sequences. The algorithm for finding LCS will tell you which elements of the two sequences belong to the LCS, and which do not. Indexes of each element of the original array that is not in LCS go into the removed array; indexes of elements of the new array that are not in LCS go into the added array.

    Here are a few examples (I parenthesized the elements of LCS):

     0  1   2   3   4   5
    (a) b  (d) (e)  g
    (a) c  (d) (e)  f   h
    

    The items of old not in LCS are 1 and 4; the items of new not in LCS are 1, 4, and 5.

    Here is another example:

     0   1   2   3
     a  (b) (c) (d)
    (b) (c) (d)  e
    

    Now added is 3 and removed is 0.

    0 讨论(0)
  • 2021-01-12 15:16

    If both arrays are already sorted in ascending order, you can find the added and removed elements with a single loop over both arrays (using two independent pointers into the array):

    NSArray *oldArray = @[@"a",@"b",@"d",@"e",@"g"];
    NSArray *newArray = @[@"a",@"c",@"d",@"e",@"f",@"h"];
    
    NSMutableArray *removedArray = [NSMutableArray array];
    NSMutableArray *addedArray = [NSMutableArray array];
    
    NSUInteger iold = 0; // index into oldArray
    NSUInteger inew = 0; // index into newArray
    
    while (iold < [oldArray count] && inew < [newArray count]) {
        // Compare "current" element of old and new array:
        NSComparisonResult c = [oldArray[iold] compare:newArray[inew]];
        if (c == NSOrderedAscending) {
            // oldArray[iold] has been removed
            [removedArray addObject:@(iold)];
            iold++;
        } else if (c == NSOrderedDescending) {
            // newArray[inew] has been added
            [addedArray addObject:@(inew)];
            inew++;
        } else {
            // oldArray[iold] == newArray[inew]
            iold++, inew++;
        }
    }
    // Process remaining elements of old array:
    while (iold < [oldArray count]) {
        [removedArray addObject:@(iold)];
        iold++;
    }
    // Process remaining elements of new array:
    while (inew < [newArray count]) {
        [addedArray addObject:@(inew)];
        inew++;
    }
    
    NSLog(@"removed: %@", removedArray);
    NSLog(@"added: %@", addedArray);
    

    Output:

    removed: (
        1,
        4
    )
    added: (
        1,
        4,
        5
    )
    
    0 讨论(0)
提交回复
热议问题