2011-06-13 14 views
7

सरणी की शुरुआत के बजाए, अंत में NSArray "टुकड़ा" करने का सबसे अच्छा तरीका क्या है (उदाहरण के लिए, अज्ञात लंबाई के NSArray के अंतिम कुछ तत्व वाले उपराय को ढूंढना)? अजगर में, आप यह पूरा करने, उदा .:सरणी के अंत से स्लाइस एनएसएआरएआर

new_list = old_list[-5:-3] 

ऑब्जेक्टिव-सी में ऐसा करने का सबसे प्राकृतिक तरीका क्या है नकारात्मक सूचकांक का उपयोग कर सकते हैं?

उत्तर

17
वहाँ

कुछ भी नहीं इस के लिए अजगर का अच्छा वाक्य रचना मिलान करने के लिए है, लेकिन आप कर सकता है:

@interface NSArray (jrdioko_slice) 
- (NSArray *) jrdioko_sliceFrom:(NSInteger)start to:(NSInteger)stop; 
@end 

आप करना चाहते हैं:

NSUInteger count = [myArray count]; 
NSArray * slice = [myArray subarrayWithRange:(NSRange){count-n, n}]; 

तुम भी ऊपर एक वर्ग NSArray के लिए की तरह कुछ लिख सकता है, इस मार्ग पर जाएं, पायथन स्रोत निश्चित रूप से अध्ययन चुकाएगा। एक स्लाइस ऑपरेशन होने पर list objectslice object बनाता है। स्लाइस ऑब्जेक्ट पर प्रासंगिक विधि PySlice_GetIndicesEx है। आपको बस उन इंडेक्स को NSRange में बदलना सावधान रहना होगा। चूंकि उस फ़ंक्शन में टिप्पणी चेतावनी देती है कि "आपके विचार से ठीक होना मुश्किल है"। (मैं इस पर एक क्रैक लेने की कोशिश करूंगा।)

अद्यतन: यहां हमारे पास NSArray पर एक टुकड़ा श्रेणी है। इंडेक्स कैलकुलेशन लॉजिक पाइथन कोड से काफी सीधे है जो मैंने ऊपर से जुड़ा हुआ है। * यह वास्तव में बहुत आसान है जैसा कि मैंने पहले सोचा था कि अगर आपको पाइथन स्लाइस के घुमावदार हिस्से के बारे में चिंता करने की ज़रूरत नहीं है। मैंने इसे कुछ परीक्षणों के माध्यम से चलाया है और ऐसा लगता है कि यह पाइथन संस्करण के समान काम करता है।

@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 

* इसलिए मुझे लगता है मैं ध्यान दें कि इस अभी भी हो सकता है "कॉपीराइट © 2001-2010 अजगर सॉफ्टवेयर फाउंडेशन Python License के लिए लिंक शामिल करने की जरूरत है और यह भी लगता है; सभी अधिकार सुरक्षित ", क्योंकि यद्यपि यह मुझे अलग-अलग-कॉपीराइट योग्य व्युत्पन्न कार्य की तरह दिखता है, मैं वकील नहीं हूं।

+3

+1 श्रेणियों के लिए +1, jrdioko_slice के लिए भी :) – Tatvamasi

+0

आपके प्रारंभिक उत्तर में, यह 'गिनती-एन' के बजाय 'गिनती-एन -1' क्यों है? – jrdioko

+2

@jrdioko: ओह, यह शर्मनाक है। एक-एक-एक त्रुटि से बचने और इसमें सही चलने का प्रयास कर रहा है। आप इसे इंगित करने के लिए सही हैं; सिर्फ गिनती होना चाहिए। –

संबंधित मुद्दे