从阵列末尾切片NSArray [英] Slice NSArray from end of array
问题描述
从数组的末尾(而不是开头)切片 NSArray
的最佳方法是什么(例如,找到包含最后几个的子数组)长度未知的 NSArray
的元素?在Python中,您可以使用负数索引来实现此目的,例如:
What is the best way to "slice" an NSArray
from the end, rather than the beginning, of the array (for example, finding the subarray containing the last few elements of a NSArray
of unknown length)? In Python, you can use negative indices to accomplish this, e.g.:
new_list = old_list[-5:-3]
Objective-C中最自然的方式是什么?
What's the most natural way to do this in Objective-C?
推荐答案
没有什么可以匹配Python的漂亮语法,但你可以这样做:
There's nothing to match Python's nice syntax for this, but you could do:
NSUInteger count = [myArray count];
NSArray * slice = [myArray subarrayWithRange:(NSRange){count-n, n}];
您还可以为 NSArray
,类似于:
@interface NSArray (jrdioko_slice)
- (NSArray *) jrdioko_sliceFrom:(NSInteger)start to:(NSInteger)stop;
@end
如果你想走这条路,Python源肯定会回报研究。 列表对象创建一个切片对象执行切片操作时。切片对象上的相关方法是 PySlice_GetIndicesEx
。您只需要小心将这些索引转换为 NSRange
。正如该功能中的评论所警告的那样这比你想象的更难做到。 (我稍后会试着解决这个问题。)
If you want to go this route, the Python source will certainly repay study. A list object creates a slice object when a slice operation is performed. The relevant method on a slice object is PySlice_GetIndicesEx
. You'll just have to be careful turning those indexes into an NSRange
. As the comment in that function warns "this is harder to get right than you might think". (I'll try to take a crack at this later.)
更新:这里我们在 NSArray上有一个切片类别
。索引计算逻辑与我上面链接的Python代码非常相似。*如果你不必担心Python切片的步幅部分,它实际上比我想象的要容易得多。我通过一些测试运行它,它似乎与Python版本一样。
UPDATE: Here we have a slice category on NSArray
. The index calculation logic is pretty much straight out of the Python code that I linked to above.* It's actually a lot easier than I thought at first if you don't have to worry about the stride part of a Python slice. I've run this through a few tests and it seems to work the same as the Python version.
@interface NSArray (WSS_Slice)
- (NSArray *)WSS_arrayBySlicingFrom:(NSInteger)start to:(NSInteger)stop;
@end
// Python allows skipping any of the indexes of a slice and supplies default
// values. Skipping an argument to a method is not possible, so (ab)use
// NSNotFound as "not specified" index value. The other way to do this would
// be with varargs, which might be even handier if one decided to implement
// the stride functionality.
enum {
WSS_SliceNoIndex = NSNotFound
};
@implementation NSArray (WSS_Slice)
- (NSArray *)WSS_arrayBySlicingFrom:(NSInteger)start to:(NSInteger)stop {
// There's an important caveat here: specifying the parameters as
// NSInteger allows negative indexes, but limits the method's
// (theoretical) use: the maximum size of an NSArray is NSUIntegerMax,
// which is quite a bit larger than NSIntegerMax.
NSUInteger count = [self count];
// Due to this caveat, bail if the array is too big.
if( count >= NSIntegerMax ) return nil;
// Define default start and stop
NSInteger defaultStart = 0;
NSInteger defaultStop = count;
// Set start to default if not specified
if( start == WSS_SliceNoIndex ){
start = defaultStart;
}
else {
// If start is negative, change it to the correct positive index.
if( start < 0 ) start += count;
// Correct for out-of-bounds index:
// If it's _still_ negative, set it to 0
if( start < 0 ) start = 0;
// If it's past the end, set it to just include the last item
if( start > count ) start = count;
}
// Perform all the same calculations on stop
if( stop == WSS_SliceNoIndex ){
stop = defaultStop;
}
else {
if( stop < 0 ) stop += count;
if( stop < 0 ) stop = 0;
if( stop > count ) stop = count;
}
// Calculate slice length with corrected indexes
NSInteger sliceLength = stop - start;
// If no slice, return a new empty array
if( sliceLength <= 0 ){
return [NSArray array];
}
else {
return [self subarrayWithRange:(NSRange){start, sliceLength}];
}
}
@end
< sub> *因此我想我需要包含一个指向 Python许可证的链接,并注意到这个可能仍然是版权所有©2001-2010 Python软件基金会;保留所有权利,因为虽然这看起来像是一个单独版权的衍生作品,但我不是律师。
*Therefore I think I need to include a link to the Python License and also note that this may still be "Copyright © 2001-2010 Python Software Foundation; All Rights Reserved", because although this looks to me like a separately-copyrightable derivative work, I ain't a lawyer.
这篇关于从阵列末尾切片NSArray的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!