根据 Objective-C 中的属性从数组中删除重复项

发布于 2024-09-28 22:56:29 字数 81 浏览 0 评论 0原文

我有一个包含自定义对象的数组。每个数组项都有一个名为“name”的字段。现在我想根据此名称值删除重复的条目。

我应该如何实现这一目标?

I have an array with custom objects. Each array item has a field named "name". Now I want to remove duplicate entries based on this name value.

How should I go about achieving this?

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

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

发布评论

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

评论(8

霊感 2024-10-05 22:56:29

我不知道框架提供了任何标准方法来执行此操作。所以你必须用代码来完成。像这样的事情应该是可行的:

NSArray* originalArray = ... // However you fetch it
NSMutableSet* existingNames = [NSMutableSet set];
NSMutableArray* filteredArray = [NSMutableArray array];
for (id object in originalArray) {
   if (![existingNames containsObject:[object name]]) {
      [existingNames addObject:[object name]];
      [filteredArray addObject:object];
   }
}

I do not know of any standard way to to do this provided by the frameworks. So you will have to do it in code. Something like this should be doable:

NSArray* originalArray = ... // However you fetch it
NSMutableSet* existingNames = [NSMutableSet set];
NSMutableArray* filteredArray = [NSMutableArray array];
for (id object in originalArray) {
   if (![existingNames containsObject:[object name]]) {
      [existingNames addObject:[object name]];
      [filteredArray addObject:object];
   }
}
孤蝉 2024-10-05 22:56:29

您可能必须自己编写这个过滤方法:

@interface NSArray (CustomFiltering)
@end

@implementation NSArray (CustomFiltering) 

- (NSArray *) filterObjectsByKey:(NSString *) key {
   NSMutableSet *tempValues = [[NSMutableSet alloc] init];
   NSMutableArray *ret = [NSMutableArray array];
   for(id obj in self) {
       if(! [tempValues containsObject:[obj valueForKey:key]]) {
            [tempValues addObject:[obj valueForKey:key]];
            [ret addObject:obj];
       }
   }
   [tempValues release];
   return ret;
}

@end

You might have to actually write this filtering method yourself:

@interface NSArray (CustomFiltering)
@end

@implementation NSArray (CustomFiltering) 

- (NSArray *) filterObjectsByKey:(NSString *) key {
   NSMutableSet *tempValues = [[NSMutableSet alloc] init];
   NSMutableArray *ret = [NSMutableArray array];
   for(id obj in self) {
       if(! [tempValues containsObject:[obj valueForKey:key]]) {
            [tempValues addObject:[obj valueForKey:key]];
            [ret addObject:obj];
       }
   }
   [tempValues release];
   return ret;
}

@end
别闹i 2024-10-05 22:56:29

我知道这是一个老问题,但还有另一种可能性,具体取决于您的需要。

苹果确实提供了一种方法来做到这一点 - 键值编码集合运算符

对象运算符让您可以对集合进行操作。在这种情况下,您需要:

@distinctUnionOfObjects

@distinctUnionOfObjects 运算符返回一个数组,其中包含运算符右侧的键路径指定的属性中的不同对象。

NSArray *distinctArray = [arrayWithDuplicates valueForKeyPath:@"@distinctUnionOfObjects.name"];

不过,在您的情况下,您需要整个对象。所以你必须做的有两件事:
1)使用@distinctUnionOfArrays代替。例如,如果您有来自其他集合的这些自定义对象,请使用@distinctUnionOfArray.myCollectionOfObjects
2) 在这些对象上实现 isEqual: 来返回它们的 .name 是否相等

I know this is an old question but here is another possibility, depending on what you need.

Apple does provide a way to do this -- Key-Value Coding Collection Operators.

Object operators let you act on a collection. In this case, you want:

@distinctUnionOfObjects

The @distinctUnionOfObjects operator returns an array containing the distinct objects in the property specified by the key path to the right of the operator.

NSArray *distinctArray = [arrayWithDuplicates valueForKeyPath:@"@distinctUnionOfObjects.name"];

In your case, though, you want the whole object. So what you'd have to do is two-fold:
1) Use @distinctUnionOfArrays instead. E.g. If you had these custom objects coming from other collections, use @distinctUnionOfArray.myCollectionOfObjects
2) Implement isEqual: on those objects to return if their .name's are equal

七度光 2024-10-05 22:56:29

我会为此受到批评...

你可以将数组转换成字典。不确定这有多有效,取决于实现和比较调用,但它确实使用了哈希映射。

//Get unique entries
NSArray *myArray = @[@"Hello", @"World", @"Hello"];
NSDictionary *uniq = [NSDictionary dictionaryWithObjects:myArray forKeys:myArray];
NSLog(@"%@", uniq.allKeys);

*注意,这可能会改变数组的顺序。

I'm going to get flak for this...

You can convert your array into a dictionary. Not sure how efficient this is, depends on the implementation and comparison call, but it does use a hash map.

//Get unique entries
NSArray *myArray = @[@"Hello", @"World", @"Hello"];
NSDictionary *uniq = [NSDictionary dictionaryWithObjects:myArray forKeys:myArray];
NSLog(@"%@", uniq.allKeys);

*Note, this may change the order of your array.

故事与诗 2024-10-05 22:56:29

如果您希望自定义 NSObject 子类在名称相等时被视为相等,您可以实现 isEqual:hash。这将允许您将对象添加到 NSSet/NSMutableSet (一组不同的对象)。

然后,您可以使用 NSSetsortedArrayUsingDescriptors: 方法轻松创建排序的 NSArray

MikeAsh 写了一篇关于实现自定义平等的相当扎实的文章: 周五问答 2010-06-18:实现平等和哈希

If you'd like your custom NSObject subclasses to be considered equal when their names are equal you may implement isEqual: and hash. This will allow you to add of the objects to an NSSet/NSMutableSet (a set of distinct objects).

You may then easily create a sorted NSArray by using NSSet's sortedArrayUsingDescriptors:method.

MikeAsh wrote a pretty solid piece about implementing custom equality: Friday Q&A 2010-06-18: Implementing Equality and Hashing

空心空情空意 2024-10-05 22:56:29

如果您担心订单问题

NSArray * newArray =
        [[NSOrderedSet orderedSetWithArray:oldArray] array]; **// iOS 5.0 and later** 

If you are worried about the order

NSArray * newArray =
        [[NSOrderedSet orderedSetWithArray:oldArray] array]; **// iOS 5.0 and later** 
桃气十足 2024-10-05 22:56:29

一行非常简单

NSArray *duplicateList = ... 

如果您不关心元素顺序(无序)

NSArray *withoutDUP1 = [[NSSet setWithArray:duplicateList] allObjects];

保持元素按顺序排列(有序)

NSArray *withoutDUP2 = [[NSOrderedSet orderedSetWithArray:duplicateList] array];

It is quite simple in one line

NSArray *duplicateList = ... 

If you don't care about elements order then (unordered)

NSArray *withoutDUP1 = [[NSSet setWithArray:duplicateList] allObjects];

Keep the elements in order then (ordered)

NSArray *withoutDUP2 = [[NSOrderedSet orderedSetWithArray:duplicateList] array];
明月夜 2024-10-05 22:56:29

实现 isEqual 以使您的对象具有可比性:

@interface SomeObject (Equality)
@end

@implementation SomeObject (Equality)

- (BOOL)isEqual:(SomeObject*)other
{
    return self.hash == other.hash;
}

- (NSUInteger)hash
{
    return self.name;///your case
}

@end

如何使用:

- (NSArray*)distinctObjectsFromArray:(NSArray*)array
{
    return [array valueForKeyPath:@"@distinctUnionOfObjects.self"];
}

Implement isEqual to make your objects comparable:

@interface SomeObject (Equality)
@end

@implementation SomeObject (Equality)

- (BOOL)isEqual:(SomeObject*)other
{
    return self.hash == other.hash;
}

- (NSUInteger)hash
{
    return self.name;///your case
}

@end

How to use:

- (NSArray*)distinctObjectsFromArray:(NSArray*)array
{
    return [array valueForKeyPath:@"@distinctUnionOfObjects.self"];
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文