स्विफ्ट में ऐरे की पहली 5 वस्तुओं को कैसे लौटाएं?


179

स्विफ्ट में, 5 पहली वस्तुओं को वापस करने के लिए ऐरे पर उच्चतर ऑर्डर विधियों का उपयोग करने का एक चतुर तरीका है? इसे करने का obj-c तरीका एक सूचकांक को सहेज रहा था, और सरणी वृद्धि सूचकांक के माध्यम से लूप था जब तक कि यह 5 नहीं था और नए सरणी को वापस कर रहा था। वहाँ के साथ यह करने के लिए एक रास्ता है filter, mapया reduce?


स्विफ्ट 4 के लिए मेरा जवाब देखें जो कि पहले nतत्वों को वापस करने के 6 अलग-अलग तरीकों को दिखाता है Array
इमानौ पेटिट

जवाबों:


445

स्विफ्ट सरणी के पहले N तत्वों को प्राप्त करने का सबसे साफ तरीका है prefix(_ maxLength: Int):

let someArray = [1, 2, 3, 4, 5, 6, 7]
let first5 = someArray.prefix(5) // 1, 2, 3, 4, 5

यह सीमा सुरक्षित होने का लाभ है। यदि आप जिस पास से गुजरते हैं prefixवह सरणी काउंट से बड़ा होता है तो यह पूरे सरणी को वापस कर देता है।

नोट: जैसा कि टिप्पणियों में बताया गया है, Array.prefixवास्तव में ए ArraySliceनहीं बल्कि रिटर्न Array। ज्यादातर मामलों में इससे कोई फर्क नहीं पड़ता है, लेकिन अगर आपको परिणाम को एक Arrayप्रकार से निर्दिष्ट करने की आवश्यकता है या इसे एक ऐसी विधि से पारित करने Arrayकी आवश्यकता है जो आपको एक परम की उम्मीद है तो आपको परिणाम को एक Arrayप्रकार में मजबूर करना होगा :let first5 = Array(someArray.prefix(5))


41
+1 ऐसा बुरा नाम विकल्प, IMHO। ऐरे है dropFirstऔर dropLast, तो हो सकता है takeFirstऔर साथ ही takeLast
माजिद

10
इसके अलावा, अगर आपको first5एक सरणी होने की आवश्यकता है, तो बस लिखेंlet first5 = Array(someArray.prefix(5))
उलाज़डिन्स

2
@mluisbrown क्षमा करें, आप से सहमत नहीं हो सकते :) :) video = video.prefix(5)Xcode में मेरी परियोजना में 7.2 त्रुटि का परिणाम है Cannot assign value of type 'ArraySlice<Video>' to type '[Video]'
ULazdins


2
@ onmyway133 prefixसंभवतः स्विफ्ट 2.x केवल है (मुझे याद नहीं है कि यह 1.x में था), लेकिन यह निश्चित रूप से किसी भी ओएस में मौजूद है जो स्विफ्ट 2.x का समर्थन करता है, जो कि iOS 7 और इसके बाद के संस्करण है। स्विफ्ट सुविधा की उपलब्धता स्विफ्ट रिलीज़ द्वारा निर्धारित की जाती है, न कि आईओएस संस्करण।
mluisbrown

99

अद्यतन: अब prefixएक सरणी के पहले n तत्वों को प्राप्त करने के लिए उपयोग करने की संभावना है । उपसर्ग का उपयोग करने के तरीके की व्याख्या के लिए @ mluisbrown के उत्तर की जाँच करें ।

मूल उत्तर: आप इसे वास्तव में बिना आसान कर सकते हैं filter, mapया reduceबस अपने सरणी की एक सीमा लौटा सकते हैं:

var wholeArray = [1, 2, 3, 4, 5, 6]
var n = 5

var firstFive = wholeArray[0..<n] // 1,2,3,4,5

71
यदि आप nएक स्विफ्ट एरे से सिर्फ पहला आइटम चाहते हैं, तो आप कर सकते हैं wholeArray.prefix(n)जिसमें सीमा सुरक्षित होने का अतिरिक्त लाभ है। यदि nसरणी से बड़ा आकार prefixपूरे सरणी को लौटाता है।
mluisbrown

4
यदि यह 5 से wholeArrayअधिक हैn
Jake Lin

@ करशालोट मैं पूरी तरह से निश्चित नहीं हूं, लेकिन मुझे लगता है कि उस समय, जहां मैंने अपना जवाब लिखा है, ऐसी कोई बात नहीं थी prefix
क्रिश्चियन

1
पहले 5 ऑब्जेक्ट प्राप्त करने के लिए इस कोड का उपयोग करें ... यह पूरी तरह से काम करता है [0,1,2,3,4,5] .enumerated ()। flatMap {$ 0 <5? $ 1: नील}
मनीष महाजन

64

अपनी आवश्यकताओं के अनुसार, स्विफ्ट 5 के साथ, आप अपनी समस्या को हल करने के लिए प्लेग्राउंड कोड के बाद 6 में से एक चुन सकते हैं ।


# 1। subscript(_:)सबस्क्रिप्ट का उपयोग करना

let array = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"]
let arraySlice = array[..<5]
//let arraySlice = array[0..<5] // also works
//let arraySlice = array[0...4] // also works
//let arraySlice = array[...4] // also works
let newArray = Array(arraySlice)
print(newArray) // prints: ["A", "B", "C", "D", "E"]

# 2। prefix(_:)विधि का उपयोग करना

जटिलता: ओ (1) यदि संग्रह के अनुरूप है RandomAccessCollection; अन्यथा, ओ ( के ), जहां कश्मीर संग्रह की शुरुआत से चयन करने के लिए तत्वों की संख्या है।

let array = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"]
let arraySlice = array.prefix(5)
let newArray = Array(arraySlice)
print(newArray) // prints: ["A", "B", "C", "D", "E"]

Apple ने कहा prefix(_:):

यदि अधिकतम लंबाई संग्रह में तत्वों की संख्या से अधिक है, तो परिणाम में संग्रह में सभी तत्व शामिल हैं।


# 3। prefix(upTo:)विधि का उपयोग करना

जटिलता: ओ (1)

let array = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"]
let arraySlice = array.prefix(upTo: 5)
let newArray = Array(arraySlice)
print(newArray) // prints: ["A", "B", "C", "D", "E"]

Apple ने कहा prefix(upTo:):

prefix(upTo:)विधि का उपयोग करना संग्रह की सबस्क्रिप्ट के रूप में आंशिक आधी खुली सीमा का उपयोग करने के बराबर है। सबस्क्रिप्ट नोटेशन को प्राथमिकता दी जाती है prefix(upTo:)


# 4। prefix(through:)विधि का उपयोग करना

let array = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"]
let arraySlice = array.prefix(through: 4)
let newArray = Array(arraySlice)
print(newArray) // prints: ["A", "B", "C", "D", "E"]

# 5। removeSubrange(_:)विधि का उपयोग करना

जटिलता: ओ ( एन ), जहां एन संग्रह की लंबाई है।

var array = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"]
array.removeSubrange(5...)
print(array) // prints: ["A", "B", "C", "D", "E"]

# 6। dropLast(_:)विधि का उपयोग करना

जटिलता: ओ (1) यदि संग्रह के अनुरूप है RandomAccessCollection; अन्यथा, ओ ( के ), जहां कश्मीर को छोड़ने के लिए तत्वों की संख्या है।

let array = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"]
let distance = array.distance(from: 5, to: array.endIndex)
let arraySlice = array.dropLast(distance)
let newArray = Array(arraySlice)
print(newArray) // prints: ["A", "B", "C", "D", "E"]

28
let a: [Int] = [0, 0, 1, 1, 2, 2, 3, 3, 4]
let b: [Int] = Array(a.prefix(5))
// result is [0, 0, 1, 1, 2]

18

स्विफ्ट 4

एक अलग समाधान:

यदि आपका सरणी बहुत छोटा है तो एक आसान इनलाइन समाधान जो दुर्घटनाग्रस्त नहीं करेगा

[0,1,2,3,4,5].enumerated().compactMap{ $0.offset < 3 ? $0.element : nil }

लेकिन इसके साथ ठीक काम करता है।

[0,1,2,3,4,5].enumerated().compactMap{ $0.offset < 1000 ? $0.element : nil }

यदि आप ऐसा करते हैं तो आमतौर पर यह दुर्घटनाग्रस्त हो जाएगा:

[0,1,2,3,4,5].prefix(upTo: 1000) // THIS CRASHES

[0,1,2,3,4,5].prefix(1000) // THIS DOESNT

3
स्विफ्ट 3 के लिए[0,1,2,3,4,5].enumerated().flatMap{ $0.offset < 1000 ? $0.element : nil }
स्टीवन ट्सू

1
धन्यवाद! यदि आप अपडेट करना चाहते हैं, तो सरणी संकलन के लिए स्विफ़्ट 4 में फ़्लैटबॉल को अब कॉम्पेक्टमैप कहा जाता है।
मणिमाल

14

किसी सरणी के पहले 5 तत्व प्राप्त करने के लिए, आपको केवल प्रश्न में सरणी को टुकड़ा करना होगा। स्विफ्ट में, आप इसे इस तरह से करते हैं array[0..<5]:।

किसी सरणी के एन पहले तत्वों को थोड़ा और अधिक कार्यात्मक और सामान्य बनाने के लिए, आप इसे करने के लिए एक विस्तार विधि बना सकते हैं। उदाहरण के लिए:

extension Array {
    func takeElements(var elementCount: Int) -> Array {
        if (elementCount > count) {
            elementCount = count
        }
        return Array(self[0..<elementCount])
    }
}

5

मैंने नवीनतम स्विफ्ट संस्करण के लिए इसे अपडेट करने के लिए मार्कस के उत्तर को थोड़ा बदल दिया, क्योंकि varआपके विधि घोषणा के अंदर अब समर्थित नहीं है:

extension Array {
    func takeElements(elementCount: Int) -> Array {
        if (elementCount > count) {
            return Array(self[0..<count])
        }
        return Array(self[0..<elementCount])
    }
}

3

स्विफ्ट 4

स्विफ्ट सरणी के पहले N तत्वों को प्राप्त करने के लिए आप इनका उपयोग कर सकते हैं prefix(_ maxLength: Int):

Array(largeArray.prefix(5))

1

बचत सरणी प्रकार के साथ 4 स्विफ्ट

extension Array {
    func take(_ elementsCount: Int) -> [Element] {
        let min = Swift.min(elementsCount, count)
        return Array(self[0..<min])
    }
}

1

स्विफ्ट 4 के लिए अपडेट:

[0,1,2,3,4,5].enumerated().compactMap{ $0 < 10000 ? $1 : nil }

स्विफ्ट 3 के लिए:

[0,1,2,3,4,5].enumerated().flatMap{ $0 < 10000 ? $1 : nil }

1
अप्रभावी समाधान। 1) आप किसी सरणी की लंबाई का अतिरिक्त अनुक्रम बनाते हैं। 2) आप सभी तत्वों के माध्यम से पुनरावृति करते हैं।
अलेक्जेंडर बेकर्ट

2
10000? वह क्या है?
बैंगऑपरेटर


1

वस्तुओं की एक सरणी के लिए आप अनुक्रम से एक विस्तार बना सकते हैं।

extension Sequence {
    func limit(_ max: Int) -> [Element] {
        return self.enumerated()
            .filter { $0.offset < max }
            .map { $0.element }
    }
}

उपयोग:

struct Apple {}

let apples: [Apple] = [Apple(), Apple(), Apple()]
let limitTwoApples = apples.limit(2)

// limitTwoApples: [Apple(), Apple()]
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.