如何通过键和值获取对象

how to get object by key and value

我有一个名为 masterMessages 的对象,其中填充了名为消息的对象。每个消息对象有五个键:

基本上我现在正在做的是在这个名为 masterMessages 的对象中查询发送给我的用户的所有消息。然后我使用:

        self.senderIds = [masterMessages valueForKeyPath:@"@distinctUnionOfObjects.senderId"];

在名为 senderIds 的数组中获取所有不同的发件人 ID (senderId)。有了这个,我将填充我的对话 table。但我想用发件人姓名 (senderName) 而不是 senderIds 填充它。我只在两个用户具有相同名称的情况下才这样做。

我正在寻找:

  1. 我怎么说 "get valueForKey:@"senderName" 对于这个 senderId

  1. 是否有更好的方式来填充我的对话table?

这是我的代码:

注意:我正在使用 parse.com

  -(void)viewWillAppear:(BOOL)animated{

NSString *userId = [[PFUser currentUser] objectId];

PFQuery *query = [PFQuery queryWithClassName:@"lean"];
[query whereKey:@"recipientId" equalTo:userId];
[query orderByDescending:@"createdAt"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
    if (error) {
        NSLog(@"Error: %@ %@", error, [error userInfo]);
    }
    else {
        // We found messages!
        masterMessages = objects;

        NSLog(@"self.messages = %@", masterMessages);

        self.senderIds = [masterMessages valueForKeyPath:@"@distinctUnionOfObjects.senderId"];

        NSLog(@"self.senderIds = %@", self.senderIds);


        [self.tableView reloadData];

    }
  }];


}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return [self.senderIds count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];

NSLog(@"self.senderIds = %@", self.senderIds);

NSString *senderDisplayName = [self.senderIds objectAtIndex:indexPath.row];

NSLog(@"sender = %@", senderDisplayName);


cell.textLabel.text = senderDisplayName;


return cell;
}


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
selectedId = [self.senderIds objectAtIndex:indexPath.row];


[self performSegueWithIdentifier:@"ShowMissionMessage" sender:self];



}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:@"ShowMissionMessage"]) {

    [segue.destinationViewController setHidesBottomBarWhenPushed:YES];
    MissionChat *missionchatviewcontroller = (MissionChat *)segue.destinationViewController;
    missionchatviewcontroller.selectedId = selectedId;
    missionchatviewcontroller.masterMessages = masterMessages;
   }
}

问题中有几个问题,一个是如何取消引用 PFObjects,我们已经解决了 。这个问题的其余部分是关于 (a) 如何使用解析对象构建数据源以支持 table 视图,以及更难的问题 (b) 如何从相关对象获取信息。

从 (b) 开始,比较难的一个:有几种方法可以关联对象。您选择一个包含相关对象 ID 的字符串类型的列是直观的(特别是如果您有 SQL 背景),但最不可取。对一对一或小型一对多关系建模的更好(最佳)方法是使用指针(如果是一对多,则为指针数组)。

所以我认为您的 senderId 和 recipientId 字符串列应该替换为称为发件人和收件人的指针类型列。这样做的巨大优势是能够急切地获取消息(或 "lean" 在您的术语中)查询中的那些指向的对象。

进行更改后,您的新改进查询如下所示:

PFQuery *query = [PFQuery queryWithClassName:@"lean"];
// notice the first change for the better here:
[query whereKey:@"recipient" equalTo:[PFUser currentUser]];
[query orderByDescending:@"createdAt"];
// notice the really valuable feature here:
[query includeKey:@"sender"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {

    // using the array of PFObjects understanding from your other question...

    for (PFObject *pfObject in objects) {
        NSString *messageBody = [pfObject objectForKey:@"messageBody"];
        // these lines here are the punch line:
        PFUser *sender = [pfObject objectForKey:@"sender"];
        NSString *senderName = [sender username];
        NSLog(@"The message %@ was sent by %@", messageBody, senderName);
    }
}];

上面要注意的重要一点是,我们能够为 @"sender" 列请求结果对象,并且因为您已将其更改为指针,并且因为您已经完成了 includeKey在查询中,现在获取了完整的对象(例如,包括 PFUser 用户名)。

现在是简单的问题(a)。现在您已经拥有来自服务器的数据,table 的数据源只不过是返回的对象。换句话说,扔掉 senderIds 数组并将其替换为:

@property(nonatomic, strong) NSArray *messages;

您的查找块变得微不足道:

[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
    self.messages = objects;
}];

numberOfRowsInSection回答messages.count,然后从cellForRowAtIndexPath...

中的对象中选择你需要的东西
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];

    PFObject *message = self.messages[indexPath.row];

    NSString *messageBody = [message objectForKey:@"messageBody"];
    PFUser *sender = [message objectForKey:@"sender"];
    NSString *senderName = [sender username];
    cell.textLabel.text = senderName;

    return cell;
}
function getObjects(obj, key, val) {
    var objects = [];
    for (var i in obj) {
        if (!obj.hasOwnProperty(i)) continue;
        if (typeof obj[i] == 'object') {
            objects = objects.concat(getObjects(obj[i], key, val));
        } else if (i == key && obj[key] == val) {
            objects.push(obj);
        }
    }
    return objects;
}
var result = getObjects(obj, 'category_id', valu.category_id);
console.log(result);
    function findObjectByKey(array, key, value) {
        for (var i = 0; i < array.length; i++) {
            if (array[i][key] === value) {
                return array[i];
            }
        }
        return null;
    }

var obj = findObjectByKey(objArray, 'id', 3);

//ES6

var obj = objArray.find(function (obj) { return obj.id === 3; });