स्विफ्ट में दो आयामी सरणी


109

मैं स्विफ्ट में 2D सरणियों के बारे में बहुत उलझन में हूं। मुझे कदम से कदम का वर्णन करें। और अगर आप गलत हैं तो क्या आप मुझे सही करेंगे।

सबसे पहले; एक खाली सरणी की घोषणा:

class test{
    var my2Darr = Int[][]()
}

दूसरी बार सरणी भरें। (जैसे my2Darr[i][j] = 0कि मैं कहां हूं, j- लूप वैरिएबल हैं)

class test {
    var my2Darr = Int[][]()
    init() {
        for(var i:Int=0;i<10;i++) {
            for(var j:Int=0;j<10;j++) {
                my2Darr[i][j]=18   /*  Is this correct?  */
            }
        }
    }
}

और अंत में, सरणी में संपादन तत्व

class test {
    var my2Darr = Int[][]()
    init() {
        ....  //same as up code
    }
    func edit(number:Int,index:Int){
        my2Darr[index][index] = number
        // Is this correct? and What if index is bigger
        // than i or j... Can we control that like 
        if (my2Darr[i][j] == nil) { ...  }   */
    }
}

क्या आपको अपने दृष्टिकोण से समस्या है?
एलेक्स वेन

2
बस आपको पता है, आपका पूरा दूसरा चरण इस पर कम हो सकता है var my2DArray = Array(count: 10, repeatedValue: Array(count: 10, repeatedValue: 18))और आपको वास्तव में एक नए बीटा में अपग्रेड करना चाहिए। Int[][]()अब मान्य सिंटैक्स नहीं है। इसे बदल दिया गया है [[Int]]()
मिक मैक्लम

1
दोहराए गए मानों का उपयोग करके 2 डी init काम नहीं करेगा। सभी पंक्तियाँ एक ही उप-सरणी की ओर इंगित करेंगी, और इस प्रकार विशिष्ट रूप से लिखने योग्य नहीं होगी।
हॉटपावर 2

जवाबों:


228

परिवर्तनशील सरणी को परिभाषित करें

// 2 dimensional array of arrays of Ints 
var arr = [[Int]]() 

या:

// 2 dimensional array of arrays of Ints 
var arr: [[Int]] = [] 

या यदि आपको पूर्वनिर्धारित आकार के एक सरणी की आवश्यकता है (जैसा कि टिप्पणियों में @ 0x7fffffff द्वारा उल्लेख किया गया है):

// 2 dimensional array of arrays of Ints set to 0. Arrays size is 10x5
var arr = Array(count: 3, repeatedValue: Array(count: 2, repeatedValue: 0))

// ...and for Swift 3+:
var arr = Array(repeating: Array(repeating: 0, count: 2), count: 3)

स्थिति में तत्व बदलें

arr[0][1] = 18

या

let myVar = 18
arr[0][1] = myVar

उप सरणी बदलें

arr[1] = [123, 456, 789] 

या

arr[0] += 234

या

arr[0] += [345, 678]

यदि आपके पास इन परिवर्तनों से पहले 0 (शून्य) का 3x2 सरणी है, तो अब आपके पास है:

[
  [0, 0, 234, 345, 678], // 5 elements!
  [123, 456, 789],
  [0, 0]
]

तो अवगत रहें कि उप सरणियाँ परस्पर हैं और आप मैट्रिक्स का प्रतिनिधित्व करने वाले प्रारंभिक सरणी को फिर से परिभाषित कर सकते हैं।

उपयोग करने से पहले आकार / सीमा की जांच करें

let a = 0
let b = 1

if arr.count > a && arr[a].count > b {
    println(arr[a][b])
}

टिप्पणी: 3 और आयामी सरणियों के लिए समान मार्कअप नियम।


ठीक है एक संदिग्ध सवाल: हम उस सरणी को कैसे असाइन करते हैं, सी में हम ऐसा करते हैं: गिरफ्तारी [i] [j] = myVar; लेकिन तेजी से जब मैं उसी तरह से करने की कोशिश करता हूं तो मुझे यह त्रुटि मिली "" [([(इंट)]]])। टाइप 'में' सबस्क्रिप्ट 'नाम का कोई सदस्य नहीं है
एंटीकोहोस

यदि आपने arrउत्तर में परिभाषित किया है तो myVarInt होना चाहिए, क्या यह है?
कीनले

हाँ, यह इंट है। और विस्तृत जवाब के लिए बहुत बहुत धन्यवाद .. अब इसका स्पष्ट: डी
एंटीकोहोस

6
स्विफ्ट 3 में, कॉपी पेस्ट करने वालों के लिए:var arr = Int(repeating: Int(repeating: 0, count: 2), count: 3)
kar

1
स्विफ्ट 4.2 में: उदाहरण के लिए, 3 पंक्ति, 2 कॉलम, 3 * 2var arr = Array(count: 2, repeatedValue: Array(count: 3, repeatedValue: 0))
Zgpeace

27

डॉक्स से:

आप वर्ग कोष्ठक के युग्मों को जोड़कर बहुआयामी सरणियाँ बना सकते हैं, जहाँ आधार प्रकार के तत्वों का नाम वर्ग वर्ग के अंतरतम युग्म में समाहित है। उदाहरण के लिए, आप वर्ग कोष्ठक के तीन सेटों का उपयोग करके पूर्णांकों का त्रि-आयामी सरणी बना सकते हैं:

var array3D: [[[Int]]] = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]

जब तत्वों को एक बहुआयामी सरणी में एक्सेस किया जाता है, तो बाईं-सबसे सबस्क्रिप्ट इंडेक्स उस इंडेक्स के तत्व को सबसे बाहरी सरणी में संदर्भित करता है। दाईं ओर का अगला सबस्क्रिप्ट इंडेक्स उस इंडेक्स के तत्व को संदर्भित करता है, जिसमें एरे में नेस्टेड है, जिसमें एक लेवल होता है। इसका मतलब यह है कि ऊपर दिए गए उदाहरण में, array3D [0] [1, 2], [3, 4]], array3D [0] [1] को संदर्भित करता है [3, 4] और array3D [0] [1] को संदर्भित करता है ] [१] का तात्पर्य मूल्य ४ से है।


17

इसे जेनेरिक स्विफ्ट 4 बनाएं

struct Matrix<T> {
    let rows: Int, columns: Int
    var grid: [T]
    init(rows: Int, columns: Int,defaultValue: T) {
        self.rows = rows
        self.columns = columns
        grid = Array(repeating: defaultValue, count: rows * columns) as! [T]
    }
    func indexIsValid(row: Int, column: Int) -> Bool {
        return row >= 0 && row < rows && column >= 0 && column < columns
    }
    subscript(row: Int, column: Int) -> T {
        get {
            assert(indexIsValid(row: row, column: column), "Index out of range")
            return grid[(row * columns) + column]
        }
        set {
            assert(indexIsValid(row: row, column: column), "Index out of range")
            grid[(row * columns) + column] = newValue
        }
    }
}


var matrix:Matrix<Bool> = Matrix(rows: 1000, columns: 1000,defaultValue:false)

matrix[0,10] = true


print(matrix[0,10])

मैंने एक 2 डी टॉरॉयडल सरणी बनाने के लिए आपके उत्तर को अनुकूलित किया। आपका बहुत बहुत धन्यवाद! gist.github.com/amiantos/bb0f313da1ee686f4f69b8b44f3cd184
ब्रैड रूट

16

जब आप उपयोग कर रहे हों तो आपको सावधान रहना चाहिए Array(repeating: Array(repeating: {value}, count: 80), count: 24)

यदि मान एक ऑब्जेक्ट है, जिसे इसके द्वारा प्रारंभ किया जाता है MyClass(), तो वे उसी संदर्भ का उपयोग करेंगे।

Array(repeating: Array(repeating: MyClass(), count: 80), count: 24)MyClassप्रत्येक सरणी तत्व में एक नया उदाहरण नहीं बनाता है । यह विधि केवल MyClassएक बार बनाता है और इसे सरणी में डालता है।

यहां बहुआयामी सरणी को इनिशियलाइज़ करने का एक सुरक्षित तरीका है।

private var matrix: [[MyClass]] = MyClass.newMatrix()

private static func newMatrix() -> [[MyClass]] {
    var matrix: [[MyClass]] = []

    for i in 0...23 {
        matrix.append( [] )

        for _ in 0...79 {
            matrix[i].append( MyClass() )
        }
    }

    return matrix
}

नमस्ते क्या हम "anyObject" प्रकार के एक्सटेंशन के रूप में सुधार कर सकते हैं?
एंटीकोहोस

संदर्भ प्रकार के साथ समस्या के बारे में अच्छी बात। हालाँकि, आप Array(repeating: {value}, could 80)ब्रेसिज़ के साथ क्यों लिखते हैं {value}? यह क्लोजर की एक सरणी पैदा करेगा, यह नहीं होगा?
डंकन सी।

या {value}"कुछ भी मान के प्रकार" (एक संदर्भ प्रकार) के लिए मेटा-नोटेशन है?
डंकन सी।

मैंने लगभग एक घंटे इस समस्या के कारण बग की तलाश में बिताए ...
मथियस वेबर


10

तेजी से 4.1 के लिए Apple दस्तावेज़ों के अनुसार आप इस संरचना का उपयोग इतनी आसानी से एक 2D सरणी बनाने के लिए कर सकते हैं:

लिंक: https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Subscripts.html

कोड नमूना:

struct Matrix {
    let rows: Int, columns: Int
    var grid: [Double]
    init(rows: Int, columns: Int) {
        self.rows = rows
        self.columns = columns
        grid = Array(repeating: 0.0, count: rows * columns)
    }
    func indexIsValid(row: Int, column: Int) -> Bool {
        return row >= 0 && row < rows && column >= 0 && column < columns
    }
    subscript(row: Int, column: Int) -> Double {
        get {
            assert(indexIsValid(row: row, column: column), "Index out of range")
            return grid[(row * columns) + column]
        }
        set {
            assert(indexIsValid(row: row, column: column), "Index out of range")
            grid[(row * columns) + column] = newValue
        }
    }
}

1
मुझें यह पसंद है। यह सी सूचक अंकगणित की याद दिलाता है। हालांकि जेनरिक का उपयोग करके इसे फिर से लिखना बेहतर होगा, इसलिए यह किसी भी डेटा प्रकार के 2-आयामी सरणियों पर लागू होगा। उस मामले के लिए, आप किसी भी मनमाने आयाम को सरणियाँ बनाने के लिए इस दृष्टिकोण का उपयोग कर सकते हैं।
डंकन सी।

1
@vacawama, शांत, आपके n- आयामी सरणी को छोड़कर सभी समाधानों के समान समस्या है जो उपयोग करने वाले सरणी को पॉप्युलेट करते हैं Array(repeating:count:)। वह टिप्पणी देखें जो मैंने आपके अन्य उत्तर पर पोस्ट की है।
डंकन सी।

6

स्विफ्ट में बहुआयामी सरणियों का उपयोग करने से पहले, प्रदर्शन पर उनके प्रभाव पर विचार करें । मेरे परीक्षणों में, चपटे सरणी ने 2D संस्करण की तुलना में लगभग 2x बेहतर प्रदर्शन किया:

var table = [Int](repeating: 0, count: size * size)
let array = [Int](1...size)
for row in 0..<size {
    for column in 0..<size {
        let val = array[row] * array[column]
        // assign
        table[row * size + column] = val
    }
}

50x50 सरणी भरने के लिए औसत निष्पादन समय: 82.9ms

बनाम

var table = [[Int]](repeating: [Int](repeating: 0, count: size), count: size)
let array = [Int](1...size)
for row in 0..<size {
    for column in 0..<size {
        // assign
        table[row][column] = val
    }
}

एक 50x50 2D सरणी को भरने के लिए औसत निष्पादन समय: 135ms

दोनों एल्गोरिदम ओ (एन ^ 2) हैं, इसलिए निष्पादन समय में अंतर तालिका को शुरू करने के तरीके से होता है।

अंत में, सबसे बुरा आप append()नए तत्वों को जोड़ने के लिए उपयोग कर रहे हैं। यह मेरे परीक्षणों में सबसे धीमा साबित हुआ:

var table = [Int]()    
let array = [Int](1...size)
for row in 0..<size {
    for column in 0..<size {
        table.append(val)
    }
}

परिशिष्ट (): 2.59 का उपयोग करके 50x50 एरे को भरने के लिए औसत निष्पादन समय

निष्कर्ष

यदि निष्पादन गति मायने रखती है तो बहुआयामी सरणियों से बचें और सूचकांक द्वारा पहुंच का उपयोग करें। 1D सरणियाँ अधिक प्रदर्शनकारी हैं, लेकिन आपका कोड समझने में थोड़ा कठिन हो सकता है।

मेरे GitHub रेपो से डेमो प्रोजेक्ट डाउनलोड करने के बाद आप प्रदर्शन परीक्षण स्वयं चला सकते हैं: https://github.com/nyisztor/swift-algorithms/tree/master/big-o-src/Big-O.playground


0

यह एक सरल रेखा में किया जा सकता है।

स्विफ्ट 5

var my2DArray = (0..<4).map { _ in Array(0..<) }

आप इसे अपनी पसंद के किसी भी वर्ग या संरचना के उदाहरणों में भी मैप कर सकते हैं

struct MyStructCouldBeAClass {
    var x: Int
    var y: Int
}

var my2DArray: [[MyStructCouldBeAClass]] = (0..<2).map { x in
    Array(0..<2).map { MyStructCouldBeAClass(x: x, y: $0)}
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.