स्विफ्ट सरणी में तत्वों का योग ढूँढना


228

स्विफ्ट में पूर्णांक के एक सरणी का योग खोजने का सबसे आसान (सबसे अच्छा) तरीका क्या है? मेरे पास एक सरणी है जिसे गुणक कहा जाता है और मैं गुणकों का योग जानना चाहूंगा।

जवाबों:


466

यह सबसे आसान / सबसे छोटा तरीका है जो मैं पा सकता हूं।

स्विफ्ट 3 और स्विफ्ट 4:

let multiples = [...]
let sum = multiples.reduce(0, +)
print("Sum of Array is : ", sum)

स्विफ्ट 2:

let multiples = [...]
sum = multiples.reduce(0, combine: +)

कुछ और जानकारी:

यह एरे की कम करने की विधि ( यहां प्रलेखन ) का उपयोग करता है , जो आपको "प्रदान किए गए क्लोजर को पुनरावर्ती रूप से लागू करके एक एकल मूल्य तक तत्वों के संग्रह को कम करने" की अनुमति देता है। हम इसे प्रारंभिक मूल्य के रूप में 0 देते हैं, और फिर, अनिवार्य रूप से, क्लोजर { $0 + $1 }। बेशक, हम इसे एकल प्लस चिह्न के लिए सरल कर सकते हैं, क्योंकि यही स्विफ्ट रोल करता है।


42
इस उत्तर के लिए धन्यवाद। यह बहुत अच्छा काम करता है और मैं सिर्फ कस्टम क्लासेस की सरणी के साथ अपना उदाहरण कोड जोड़ना चाहता हूं:let totalSum = self.cheques.reduce(0) { $0 + $1.amount}
Libor Zapletal

2
महान जवाब लेकिन लापता पैरामीटर नाम combine। होना चाहिए multiples.reduce(0, combine: +)
इवगेनी

2
क्या यह लूप के लिए तेजी से है?
लोरेंजो

1
@SwiftMatt flatMapएक एकल आयाम सरणी पर इसे समतल करने के लिए पहले इस पर उपयोग करने का प्रयास करें । multiArray.flatMap{$0}.reduce(0, combine: +)
सामह

2
@lorenzo - नवीनतम स्विफ्ट और XCode के साथ एक iPhone 7 पर परीक्षण (UInt32 अतिप्रवाह को रोकने के लिए 256 पर छाया हुआ यादृच्छिक UInt32 से भरा एक सरल सरणी) दिलचस्प रूप से 'लूप' के लिए केवल एक बाल तेजी से दिखता है (1.941 सेकंड बनाम 2.137 सेकंड) , हालांकि वह लाभ 100,000 मूल्यों (प्रत्येक 0.23 सेकंड) पर मौजूद नहीं है । IMMB, कोड स्पष्टता 32MB सरणियों से निपटने पर भी यहां किसी भी बहुत मामूली प्रदर्शन लागत के लायक है।
टॉम डिब्बल

84

वस्तुओं के गुणों को योग करने के लिए 3+ एक लाइनर स्विफ्ट

var totalSum = scaleData.map({$0.points}).reduce(0, +)

जहां बिंदु मेरे कस्टम ऑब्जेक्ट स्केलडैट में संपत्ति है जिसे मैं कम करने की कोशिश कर रहा हूं



22

में स्विफ्ट 4 तुम भी करने के लिए अनुक्रम तत्वों विवश कर सकते हैं संख्यात्मक पालन अनुक्रम में सभी तत्वों का योग वापस जाने के लिए प्रोटोकॉल

extension Sequence where Element: Numeric {
    /// Returns the sum of all elements in the collection
    func sum() -> Element { return reduce(0, +) }
}

संपादित करें / अद्यतन:

Xcode 10.2 • स्विफ्ट 5 या बाद में

हम संग्रह में सभी तत्वों का योग वापस करने के लिए नए AdditiveArithmetic प्रोटोकॉल के अनुक्रम तत्वों को सीमित कर सकते हैं

extension Sequence where Element: AdditiveArithmetic {
    func sum() -> Element {
        return reduce(.zero, +)
    }
}

Xcode 11 • स्विफ्ट 5.1 या बाद में

extension Sequence where Element: AdditiveArithmetic {
    func sum() -> Element { reduce(.zero, +) }
}

let numbers = [1,2,3]
numbers.sum()    // 6

let doubles = [1.5, 2.7, 3.0]
doubles.sum()    // 7.2

1
बढ़िया, अच्छा समाधान!
सबीलैंड


10

स्विफ्ट 4 उदाहरण

class Employee {
    var salary: Int =  0
    init (_ salary: Int){
        self.salary = salary
    }
}

let employees = [Employee(100),Employee(300),Employee(600)]
var sumSalary = employees.reduce(0, {$0 + $1.salary}) //1000

9

स्विफ्ट 3

यदि आपके पास जेनेरिक ऑब्जेक्ट्स की एक सरणी है और आप कुछ ऑब्जेक्ट प्रॉपर्टी का योग करना चाहते हैं:

class A: NSObject {
    var value = 0
    init(value: Int) {
       self.value = value
    }
}

let array = [A(value: 2), A(value: 4)]      
let sum = array.reduce(0, { $0 + $1.value })
//                           ^       ^
//                        $0=result  $1=next A object
print(sum) // 6 

छोटे रूप के बावजूद, कई बार आप क्लासिक फॉर-साइकिल पसंद कर सकते हैं:

let array = [A(value: 2), A(value: 4)]
var sum = 0
array.forEach({ sum += $0.value}) 
// or
for element in array {
   sum += element.value
}

1
सियाओ लुका, यहाँ मेरा समाधान है: array.map ({$ 0.value})। कम (0, +)
Ivailo Kanev

इस तरह आप अधिक कोड और वेतन वृद्धि जटिलता लिखते हैं .. तो, क्यों?
लुका दावानजो

6

के सरल तरीके के बारे में कैसे

for (var i = 0; i < n; i++) {
 sum = sum + Int(multiples[i])!
}

// जहां n = सरणी में तत्वों की संख्या


ध्यान दें कि स्विफ्ट 3 में यह अब मान्य नहीं है क्योंकि लूप्स के लिए सी शैली को भाषा से हटा दिया गया है। इसके बजाय इन-लूप के लिए उपयोग करें, स्विफ्ट आंतरिक रूप से सूचकांक का ट्रैक रखता है।
डोनर्ब

1
यह काम नहीं करेगा। आपको पहले 0 का योग करना है। कम करने की सुंदरता यह है कि यह आपको प्रारंभिक मूल्य के बारे में सोचने की याद दिलाता है।
MarkAurelius

var sum = 0 ; for n in multiples { sum += n }हालांकि मैं कम उपयोग करूंगा।
जेरेमीप

2

एक संभावित समाधान: इसके लिए एक उपसर्ग ऑपरेटर को परिभाषित करें। एपीएल के अनुसार "+ /" ऑपरेटर को कम करें (जैसे जीएनयू एपीएल)

यहाँ एक अलग दृष्टिकोण का एक सा।

एक प्रोटोकॉल एन जेनेरिक प्रकार का उपयोग करने से हमें इस ऑपरेटर को डबल, फ्लोट और इंट सरणी प्रकारों पर उपयोग करने की अनुमति मिलती है

protocol Number 
{
   func +(l: Self, r: Self) -> Self
   func -(l: Self, r: Self) -> Self
   func >(l: Self, r: Self) -> Bool
   func <(l: Self, r: Self) -> Bool
}

extension Double : Number {}
extension Float  : Number {}
extension Int    : Number {}

infix operator += {}

func += <T:Number> (inout left: T, right: T)
{
   left = left + right
}

prefix operator +/ {}

prefix func +/ <T:Number>(ar:[T]?) -> T?
{
    switch true
    {
    case ar == nil:
        return nil

    case ar!.isEmpty:
        return nil

    default:
        var result = ar![0]
        for n in 1..<ar!.count
        {
            result += ar![n]
        }
        return result
   }
}

ऐसे उपयोग करें:

let nmbrs = [ 12.4, 35.6, 456.65, 43.45 ]
let intarr = [1, 34, 23, 54, 56, -67, 0, 44]

+/nmbrs     // 548.1
+/intarr    // 145

(स्विफ्ट 2.2 के लिए अद्यतन, Xcode संस्करण 7.3 में परीक्षण किया गया)


इसके साथ एक मुद्दा यह है कि अक्सर (कम से कम, जब बड़े सरणियों से निपटते हैं) आपको घटकों की तुलना में एक अलग प्रकार के योग की आवश्यकता होगी। उदाहरण के लिए, यदि आपके पास 0 से 2 ^ 32-1 (पूर्व, आर्क 4random ()) द्वारा आबादी वाले सरगम ​​को चलाने वाला एक मिलियन UInt32s है, तो उन्हें जोड़ने से आपका UInt32 "योग" मान हर बार ओवरफ्लो हो जाएगा।
टॉम डिबल

2

स्विफ्ट 3.0

मैं एक ही समस्या थी, मैं प्रलेखन Apple इस समाधान पर पाया।

let numbers = [1, 2, 3, 4]
let addTwo: (Int, Int) -> Int = { x, y in x + y }
let numberSum = numbers.reduce(0, addTwo)
// 'numberSum' == 10

लेकिन, मेरे मामले में मेरे पास ऑब्जेक्ट की एक सूची थी, तो मुझे अपनी सूची के मूल्य को बदलने की आवश्यकता थी:

let numberSum = self.list.map({$0.number_here}).reduce(0, { x, y in x + y })

यह काम मेरे लिए।


0
@IBOutlet var valueSource: [MultipleIntBoundSource]!

private var allFieldsCount: Int {
    var sum = 0
    valueSource.forEach { sum += $0.count }
    return sum
}

नेस्टेड मापदंडों के लिए इस एक का उपयोग किया


0

इसे सरल रखें...

var array = [1, 2, 3, 4, 5, 6, 7, 9, 0]
var n = 0
for i in array {
    n += i
}
print("My sum of elements is: \(n)")

आउटपुट:

मेरे तत्वों का योग है: ३:


0

मेरे लिए, यह संपत्ति का उपयोग करने जैसा था

    let blueKills = match.blueTeam.participants.reduce(0, { (result, participant) -> Int in
        result + participant.kills
    })

-2

स्विफ्ट 3

यहां प्रदर्शित सभी विकल्पों में से, यह वह है जो मेरे लिए काम करता है।

let arr = [6,1,2,3,4,10,11]


var sumedArr = arr.reduce(0, { ($0 + $1)})
print(sumedArr)

यह सिर्फ एक और जवाब की एक प्रति है
एशले मिल्स


-4

इस बारे में मेरा दृष्टिकोण है। हालाँकि मेरा मानना ​​है कि सबसे अच्छा समाधान उपयोगकर्ता उपयोगकर्ता नाम tbd से उत्तर है

var i = 0 
var sum = 0
let example = 0
for elements in multiples{
    i = i + 1
    sum = multiples[ (i- 1)]
    example = sum + example
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.