【问题标题】:Replace an Dictionary object in Array using NSPredicate使用 NSPredicate 替换 Array 中的 Dictionary 对象
【发布时间】:2016-12-30 07:08:54
【问题描述】:

我在 Array 中有一个字典对象。

我想用新字典替换这个对象。

两者都有相同的 order_id。

目前我正在这样做,我如何使用 NSPredicate 来做到这一点。

NSMutableArray *orderList=[[NSUserDefaults standardUserDefaults]  objectForKey:@"Orders"];

        //2. Find and replace the object/OrdeDetails.
        for(int i=0;i<orderList.count;i++){

            NSDictionary *dictionary=orderList[i];

            if([dictionary[@"order_id"] isEqualToString:OrderDetails[@"order_id"]]){

                [orderList replaceObjectAtIndex:i withObject:OrderDetails];

                break;
            }


        }

【问题讨论】:

  • 如果上述方法有效,您为什么要为此使用 NSPredicate?
  • 你不能用NSPredicate替换对象,你可以简单地找到那个对象。
  • 是的,我认为我们可以使用 NSPredicate 进行查找。所以我们可以跳过几行for循环。但是我认为for循环很好。

标签: ios objective-c iphone nsdictionary nspredicate


【解决方案1】:

检查此代码:

 NSPredicate *resultPredicate = [NSPredicate
                                        predicateWithFormat:@"SELF.order_id contains[cd] %@",OrderDetails[@"order_id"]];
 NSMutableArray *arrOrders = [[NSMutableArray alloc]init];
    [arrOrders addObjectsFromArray:[[NSUserDefaults standardUserDefaults] objectForKey:@"Orders"]];

 NSArray *filteredOrder = [arrOrders filteredArrayUsingPredicate:resultPredicate];

 if ([filteredOrder count] > 0) {
       NSUInteger index = [arrOrders indexOfObject:[filteredOrder objectAtIndex:0]];
       if (index != NSNotFound) {
           [arrOrders replaceObjectAtIndex:index withObject:OrderDetails];
       }
}

【讨论】:

  • 比我的回答更合适。
【解决方案2】:

您不能用NSPredicate 替换对象,但是您可以搜索它然后进行替换。

好吧,只是在没有测试的情况下编造了这个,但我确实认为它有一个有效的语法。

您可以以此为基础,或者希望您了解使用谓词的逻辑。

// construct the predicate with the given condition
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"order_id = %@",dictionary[@"order_id"]];

// this will filter the array according to the given predicate. if there are more than 1 entries with the given condition then you should handle that this only handle unique entries
NSArray *array = [orderList filteredArrayUsingPredicate:predicate];

// assuming that order_id is unique
NSInteger index = [orderList indexOfObject:[array lastObject]];
if (index != NSNotFound) // check if index is existing
  [orderList replaceObjectAtIndex:index withObject:orderDetails]; // replace the object with the desired object

【讨论】:

  • 是的 Joshua,这就是方法,但有点棘手,否则 for 循环很好。谢谢@Joshua
  • 不是很棘手,但只需要了解谓词的工作原理。我认为这是了解 NSPredicate cheat sheet 的好方法
  • 所有答案看起来都一样,我的答案需要有一些指针理解,但我仍然会使用 for 循环。它不那么复杂。
【解决方案3】:

如果我想完美匹配,我会使用 LIKE。虽然我不确定。 取自链接cheat sheet

    NSPredicate *predicateSearchOrder=[NSPredicate predicateWithFormat:@"SELF.order_id LIKE[cd] %@",[responsedDict valueForKey:@"order_id"]];
            //
            //        //It will be only one object with order id.

NSArray *searchedArray=[orderList filteredArrayUsingPredicate:predicateSearchOrder];

if(searchedArray.count>0){
            NSDictionary *toModiFyDictionary=searchedArray[0];
            toModiFyDictionary=OrderDetails;
}

这也有效

【讨论】:

    【解决方案4】:

    如果你使用的是 Swift,那非常简单。

    public class Test : NSObject {
        class func test() -> Void {
            var array : [Dictionary<String, String>] = []
    
            let dic: Dictionary<String, String> = ["order_id" : "111", "name" : "good1"]
            let dic2: Dictionary<String, String> = ["order_id" : "222", "name" : "good2"]
    
            let dic3: Dictionary<String, String> = ["order_id" : "111", "name" : "good3"]
            array.append(dic)
            array.append(dic2)
    
            let result = array.map { (elem) -> [String : String] in
                if elem["order_id"] == "111" {
                    return dic3
                }
                return elem
            }
            print("result = \(result)") 
        }
    }
    

    【讨论】:

    • 本质上也是一个for循环
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多