2015-09-21 8 views
6

यदि मैं एक सरणी को गिनना चाहता हूं (map() फ़ंक्शन के लिए कहें जहां मुझे इसके मूल्य के साथ तत्व की अनुक्रमणिका का उपयोग करने की आवश्यकता होगी), तो मैं enumerate() फ़ंक्शन का उपयोग कर सकता हूं। उदाहरण के लिए:मूल सूचकांक का उपयोग करके एक टुकड़ा कैसे गणना करें?

import Foundation 

let array: [Double] = [1, 2, 3, 4] 

let powersArray = array.enumerate().map() { 
    pow($0.element, Double($0.index)) 
} 

print("array == \(array)") 
print("powersArray == \(powersArray)") 

// array == [1.0, 2.0, 3.0, 4.0] 
// powersArray == [1.0, 2.0, 9.0, 64.0] <- As expected 

अब, अगर मैं सरणी से कुछ उप अनुक्रम का उपयोग करना चाहते, मैं एक slice इस्तेमाल कर सकते हैं, और यह के रूप में मैं मूल सरणी में प्रयोग करेंगे मुझे सिर्फ एक ही सूचकांक का उपयोग करने की अनुमति होगी (जो मैं चाहता हूं कि अगर मैं एक्सेसर for लूप में उपयोग करता हूं तो मैं वही चाहता हूं। उदा .:

let range = 1..<(array.count - 1) 
let slice = array[range] 
var powersSlice = [Double]() 

for index in slice.indices { 
    powersSlice.append(pow(slice[index], Double(index))) 
} 

print("powersSlice == \(powersSlice)") 

// powersSlice == [2.0, 9.0] <- As expected 

हालांकि, मैं जैसे मैं मूल सरणी के साथ किया था enumerate().map() दृष्टिकोण का उपयोग करने तो मैं पूरी तरह से अलग व्यवहार पाने की कोशिश करनी चाहिए,। slice के सूचकांकों की सीमा के बजाय मैं एक नया, 0-आधारित रेंज मिलेगा:

let powersSliceEnumerate = slice.enumerate().map() { 
    pow($0.element, Double($0.index)) 
} 

print("powersSliceEnumerate == \(powersSliceEnumerate)") 

// powersSliceEnumerate == [1.0, 3.0] <- Not as expected 

प्रश्न वहाँ एक सभ्य तरीका है कि क्या है (यानी मैनुअल ऑफसेट, या कुछ का उपयोग कर समायोजन के बिना) का उपयोग कर एक टुकड़ा की गणना करने में अपने स्वयं के सूचकांक और स्वत: जेनरेट 0-आधारित वाले नहीं?

+1

अपने प्रश्न का उत्तर है, लेकिन आप 'जाने powersSlice = टुकड़ा के साथ के लिए लूप की जगह ले सकता .indices.map {पाउ (टुकड़ा [$ 0], डबल ($ 0))} ' –

+0

धन्यवाद, @MartinR। मैं आपके सुझाव को 'एन्युमरेट' जेनरेटेड इंडेक्स रेंज को ऑफ़सेट करने से बेहतर कामकाज के रूप में दिमाग में रखूंगा। – courteouselk

उत्तर

4

enumerate()(n, elem) जोड़े, जहां n रों शून्य से शुरू लगातार Int रों हैं का एक अनुक्रम देता है। यह समझ में आता है क्योंकि यह SequenceType के लिए एक प्रोटोकॉल एक्सटेंशन विधि है, और एक मनमाना अनुक्रम आवश्यक रूप से तत्वों से जुड़े इंडेक्स नहीं है।

आप अपने अपेक्षित परिणाम मिलेगा

let powersSlice = slice.indices.map { pow(slice[$0], Double($0)) } 

या

let powersSlice = zip(slice.indices, slice).map { pow($1, Double($0)) } 

बाद दृष्टिकोण के साथ मनमाना संग्रह के लिए एक प्रोटोकॉल विस्तार विधि के लिए सामान्यीकृत किया जा सकता है:

extension CollectionType { 
    func indexEnumerate() -> AnySequence<(index: Index, element: Generator.Element)> { 
     return AnySequence(zip(indices, self)) 
    } 
} 

यह (index, elem) जोड़े का अनुक्रम देता है जहां index संग्रह की एक अनुक्रमणिका है और elem संबंधित तत्व है। AnySequence कॉलर से zip() से विशिष्ट प्रकार Zip2Sequence<RangeGenerator<Self.Index>, Self> "छिपाने" के लिए उपयोग किया जाता है।

उदाहरण: स्विफ्ट 3 के लिए

let powersSliceEnumerate = slice.indexEnumerate().map() { pow($0.element, Double($0.index)) } 
print("powersSliceEnumerate == \(powersSliceEnumerate)") 
// powersSliceEnumerate == [2.0, 9.0] 

अद्यतन:

extension Collection { 
    func indexEnumerate() -> AnySequence<(Indices.Iterator.Element, Iterator.Element)> { 
     return AnySequence(zip(indices, self)) 
    } 
} 
नहीं
+0

उत्कृष्ट। धन्यवाद। – courteouselk

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