从 NSSet 获取对象

发布于 2024-09-25 15:29:41 字数 53 浏览 3 评论 0原文

如果您无法从 NSSet 中使用 objectAtIndex: 获取对象,那么如何检索对象?

If you can't get an object with objectAtIndex: from an NSSet then how do you retrieve objects?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

离不开的别离 2024-10-02 15:29:41

一个集合有多个用例。您可以枚举(例如使用 enumerateObjectsUsingBlock 或 NSFastEnumeration),调用 containsObject 用于测试成员资格,使用 anyObject 获取成员(不是随机的),或使用 所有对象

当您不想重复、不关心顺序并且想要快速进行成员资格测试时,集合是合适的。

There are several use cases for a set. You could enumerate through (e.g. with enumerateObjectsUsingBlock or NSFastEnumeration), call containsObject to test for membership, use anyObject to get a member (not random), or convert it to an array (in no particular order) with allObjects.

A set is appropriate when you don't want duplicates, don't care about order, and want fast membership testing.

初雪 2024-10-02 15:29:41

NSSet 没有方法 objectAtIndex:

尝试调用 allObjects ,它返回所有对象的 NSArray 。

NSSet doesn't have a method objectAtIndex:

Try calling allObjects which returns an NSArray of all the objects.

颜漓半夏 2024-10-02 15:29:41

如果您有某种唯一标识符来选择所需的对象,则可以使用filteredSetUsingPredicate。

首先创建谓词(假设对象中的唯一 id 称为“标识符”并且它是一个 NSString):

NSPredicate *myPredicate = [NSPredicate predicateWithFormat:@"identifier == %@", identifier];

然后使用谓词选择对象:

NSObject *myChosenObject = [mySet filteredSetUsingPredicate:myPredicate].anyObject;

it is possible to use filteredSetUsingPredicate if you have some kind of unique identifier to select the object you need.

First create the predicate (assuming your unique id in the object is called "identifier" and it is an NSString):

NSPredicate *myPredicate = [NSPredicate predicateWithFormat:@"identifier == %@", identifier];

And then choose the object using the predicate:

NSObject *myChosenObject = [mySet filteredSetUsingPredicate:myPredicate].anyObject;
妄想挽回 2024-10-02 15:29:41

NSArray *myArray = [myNSSet allObjects];

MyObject *object = [myArray objectAtIndex:(NSUInteger *)]

将 NSUInteger 替换为所需对象的索引。

NSArray *myArray = [myNSSet allObjects];

MyObject *object = [myArray objectAtIndex:(NSUInteger *)]

replace NSUInteger with the index of your desired object.

鸩远一方 2024-10-02 15:29:41

对于 Swift3 和iOS10:

//your current set
let mySet : NSSet
//targetted index
let index : Int
//get object in set at index
let object = mySet.allObjects[index]

For Swift3 & iOS10 :

//your current set
let mySet : NSSet
//targetted index
let index : Int
//get object in set at index
let object = mySet.allObjects[index]
白首有我共你 2024-10-02 15:29:41

NSSet 使用 isEqual: 方法(您放入该集合中的对象必须重写该方法,此外,还必须覆盖哈希方法)来确定对象是否在其中。

因此,例如,如果您有一个通过 id 值定义其唯一性的数据模型(假设该属性是:

@property NSUInteger objectID;

那么您将实现 isEqual: as

- (BOOL)isEqual:(id)object
{
  return (self.objectID == [object objectID]);
}

并且您可以实现 hash:

- (NSUInteger)hash
{
 return self.objectID;  // to be honest, I just do what Apple tells me to here
                       // because I've forgotten how Sets are implemented under the hood
}

然后,您可以获得具有该 ID 的对象(如以及检查它是否在 NSSet 中):

MyObject *testObject = [[MyObject alloc] init];
testObject.objectID = 5; // for example.  

// I presume your object has more properties which you don't need to set here 
// because it's objectID that defines uniqueness (see isEqual: above)

MyObject *existingObject = [mySet member: testObject];

// now you've either got it or existingObject is nil

但是,是的,从 NSSet 中获取某些内容的唯一方法是首先考虑定义其唯一性的方法,

我还没有测试更快的方法,但我避免使用。枚举,因为这可能是线性的,而使用 member: 方法会快得多,这是更喜欢使用 NSSet 而不是 NSArray 的原因之一。

NSSet uses the method isEqual: (which the objects you put into that set must override, in addition, the hash method) to determine if an object is inside of it.

So, for example if you have a data model that defines its uniqueness by an id value (say the property is:

@property NSUInteger objectID;

then you'd implement isEqual: as

- (BOOL)isEqual:(id)object
{
  return (self.objectID == [object objectID]);
}

and you could implement hash:

- (NSUInteger)hash
{
 return self.objectID;  // to be honest, I just do what Apple tells me to here
                       // because I've forgotten how Sets are implemented under the hood
}

Then, you can get an object with that ID (as well as check for whether it's in the NSSet) with:

MyObject *testObject = [[MyObject alloc] init];
testObject.objectID = 5; // for example.  

// I presume your object has more properties which you don't need to set here 
// because it's objectID that defines uniqueness (see isEqual: above)

MyObject *existingObject = [mySet member: testObject];

// now you've either got it or existingObject is nil

But yeah, the only way to get something out of a NSSet is by considering that which defines its uniqueness in the first place.

I haven't tested what's faster, but I avoid using enumeration because that might be linear whereas using the member: method would be much faster. That's one of the reasons to prefer the use of NSSet instead of NSArray.

家住魔仙堡 2024-10-02 15:29:41
for (id currentElement in mySet)
{
    // ** some actions with currentElement 
}
for (id currentElement in mySet)
{
    // ** some actions with currentElement 
}
追星践月 2024-10-02 15:29:41

大多数时候,您并不关心从一组中获取一个特定的对象。您关心的是测试集合是否包含对象。这就是集合的好处。当您想查看某个对象是否在集合中时,集合比数组快得多。

如果您不关心获得哪个对象,请使用 -anyObject 它只为您提供集合中的一个对象,就像将手放入袋子中并抓起某物一样。

Dog *aDog = [dogs anyObject]; // dogs is an NSSet of Dog objects

如果您关心获得的对象,请使用 -member 来返回该对象,如果它不在集合中,则使用 nil 。在调用该对象之前,您需要已经拥有该对象。

Dog *spot = [Dog dogWithName:@"Spot"];
// ...
Dog *aDog = [dogs member:spot]; // Returns the same object as above

您可以在 Xcode 中运行以下一些代码来了解更多信息

NSString *one = @"One";
NSString *two = @"Two";
NSString *three = @"Three";

NSSet *set = [NSSet setWithObjects:one, two, three, nil];

// Can't use Objective-C literals to create a set.
// Incompatible pointer types initializing 'NSSet *' with an expression of type 'NSArray *'
//  NSSet *set = @[one, two, three];

NSLog(@"Set: %@", set);
// Prints looking just like an array but is actually not in any order
//Set: {(
//     One,
//     Two,
//     Three
//     )}

// Get a random object
NSString *random = [set anyObject];
NSLog(@"Random: %@", random); // Random: One

// Iterate through objects. Again, although it prints in order, the order is a lie
for (NSString *aString in set) {
    NSLog(@"A String: %@", aString);
}

// Get an array from the set
NSArray *array = [set allObjects];
NSLog(@"Array: %@", array);

// Check for an object
if ([set containsObject:two]) {
    NSLog(@"Set contains two");
}

// Check whether a set contains an object and return that object if it does (nil if not)
NSString *aTwo = [set member:two];
if (aTwo) {
    NSLog(@"Set contains: %@", aTwo);
}

Most of the time you don't care about getting one particular object from a set. You care about testing to see if a set contains an object. That's what sets are good for. When you want to see if an object is in a collection sets are much faster than arrays.

If you don't care about which object you get, use -anyObject which just gives you one object from the set, like putting your hand in a bag and grabbing something.

Dog *aDog = [dogs anyObject]; // dogs is an NSSet of Dog objects

If you care about what object you get, use -member which gives you back the object, or nil if it's not in the set. You need to already have the object before you call it.

Dog *spot = [Dog dogWithName:@"Spot"];
// ...
Dog *aDog = [dogs member:spot]; // Returns the same object as above

Here's some code you can run in Xcode to understand more

NSString *one = @"One";
NSString *two = @"Two";
NSString *three = @"Three";

NSSet *set = [NSSet setWithObjects:one, two, three, nil];

// Can't use Objective-C literals to create a set.
// Incompatible pointer types initializing 'NSSet *' with an expression of type 'NSArray *'
//  NSSet *set = @[one, two, three];

NSLog(@"Set: %@", set);
// Prints looking just like an array but is actually not in any order
//Set: {(
//     One,
//     Two,
//     Three
//     )}

// Get a random object
NSString *random = [set anyObject];
NSLog(@"Random: %@", random); // Random: One

// Iterate through objects. Again, although it prints in order, the order is a lie
for (NSString *aString in set) {
    NSLog(@"A String: %@", aString);
}

// Get an array from the set
NSArray *array = [set allObjects];
NSLog(@"Array: %@", array);

// Check for an object
if ([set containsObject:two]) {
    NSLog(@"Set contains two");
}

// Check whether a set contains an object and return that object if it does (nil if not)
NSString *aTwo = [set member:two];
if (aTwo) {
    NSLog(@"Set contains: %@", aTwo);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文