从NSSet获取对象

时间:2021-12-24 16:53:04

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

如果您无法从NSSet中获取对象,那么如何检索对象呢?

7 个解决方案

#1


133  

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.

一个集合有几个用例,您可以通过(例如使用枚举objectsusingblock或NSFastEnumeration)来枚举,调用containsObject来测试成员,使用anyObject获取成员(不是随机的),或者使用allobject将它转换成一个数组(没有特定的顺序)。

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

当您不希望重复、不关心订单、希望快速的成员资格测试时,设置是合适的。

#2


29  

NSSet doesn't have a method objectAtIndex:

NSSet没有objectAtIndex方法:

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

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

#3


17  

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

如果您有某种惟一的标识符来选择需要的对象,那么可以使用filteredSetUsingPredicate。

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

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

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

And then choose the object using the predicate:

然后使用谓词选择对象:

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

#4


12  

NSArray *myArray = [myNSSet allObjects];

NSArray *myArray = [myNSSet allobject];

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

replace NSUInteger with the index of your desired object.

用所需对象的索引替换NSUInteger。

#5


6  

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.

NSSet使用方法isEqual:(在这个集合中放入的对象必须重写,另外,这个hash方法)来确定一个对象是否在它的内部。

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

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

@property NSUInteger objectID;

then you'd implement isEqual: as

然后实现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:

然后,您可以得到一个具有该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

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

但是,从NSSet中得到一些东西的唯一方法是考虑它首先定义了它的唯一性。

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.

我还没有测试什么更快,但是我避免使用枚举,因为它可能是线性的,而使用member: method会更快。这就是为什么选择使用NSSet而不是NSArray的原因之一。

#6


5  

For Swift3 & iOS10 :

Swift3 & iOS10:

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

#7


0  

for (id currentElement in mySet)
{
    // ** some actions with currentElement 
}

#1


133  

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.

一个集合有几个用例,您可以通过(例如使用枚举objectsusingblock或NSFastEnumeration)来枚举,调用containsObject来测试成员,使用anyObject获取成员(不是随机的),或者使用allobject将它转换成一个数组(没有特定的顺序)。

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

当您不希望重复、不关心订单、希望快速的成员资格测试时,设置是合适的。

#2


29  

NSSet doesn't have a method objectAtIndex:

NSSet没有objectAtIndex方法:

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

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

#3


17  

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

如果您有某种惟一的标识符来选择需要的对象,那么可以使用filteredSetUsingPredicate。

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

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

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

And then choose the object using the predicate:

然后使用谓词选择对象:

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

#4


12  

NSArray *myArray = [myNSSet allObjects];

NSArray *myArray = [myNSSet allobject];

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

replace NSUInteger with the index of your desired object.

用所需对象的索引替换NSUInteger。

#5


6  

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.

NSSet使用方法isEqual:(在这个集合中放入的对象必须重写,另外,这个hash方法)来确定一个对象是否在它的内部。

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

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

@property NSUInteger objectID;

then you'd implement isEqual: as

然后实现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:

然后,您可以得到一个具有该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

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

但是,从NSSet中得到一些东西的唯一方法是考虑它首先定义了它的唯一性。

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.

我还没有测试什么更快,但是我避免使用枚举,因为它可能是线性的,而使用member: method会更快。这就是为什么选择使用NSSet而不是NSArray的原因之一。

#6


5  

For Swift3 & iOS10 :

Swift3 & iOS10:

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

#7


0  

for (id currentElement in mySet)
{
    // ** some actions with currentElement 
}