সুইফটে দ্বিমাত্রিক অ্যারে


109

আমি সুইফটে 2 ডি অ্যারে সম্পর্কে এত বিভ্রান্ত হয়ে পড়েছি। আমাকে ধাপে ধাপে বর্ণনা করতে দিন। এবং আপনি যদি ভুল হয়ে থাকেন তবে দয়া করে আমাকে সংশোধন করবেন?

সবার আগে; একটি খালি অ্যারের ঘোষণা:

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

দ্বিতীয়ত অ্যারে পূরণ করুন। (যেমন my2Darr[i][j] = 0আমি, জে লুপ ভেরিয়েবলের জন্য যেখানে)

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
2D টি পুনরাবৃত্তি মান ব্যবহার করে কাজ করবে না। সমস্ত সারি একই উপ-অ্যারেতে নির্দেশ করবে এবং এইভাবে স্বতন্ত্রভাবে লিখনযোগ্য হবে না।
হটপাউ

উত্তর:


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]

এই পরিবর্তনগুলির আগে যদি আপনার কাছে 3x2 অ্যারে 0 (জিরো) থাকে তবে এখন আপনার কাছে রয়েছে:

[
  [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 এবং এন মাত্রিক অ্যারেগুলির জন্য একই মার্কআপ বিধি up


ঠিক আছে একটি নোংরা প্রশ্ন: আমরা কীভাবে সেই অ্যারে নির্ধারণ করি, সি তে আমরা এর মতো করি: আরর [i] [জে] = মাইভার; তবে দ্রুত যখন আমি একইভাবে চেষ্টা করার চেষ্টা করি তখন আমি এই ত্রুটিটি পেয়েছি "'[([(ইন্টার))])]। টাইপ করুন' সাবস্ক্রিপ্ট '" নামে সদস্য নেই
এন্টিওখোস

যদি আপনি arrউত্তর হিসাবে সংজ্ঞায়িত করে থাকেন তবে myVarইন্টার হওয়া উচিত, তাই না?
কেনেল

হ্যাঁ এটা অন্তর্নিহিত। এবং বিস্তারিত উত্তরের জন্য আপনাকে অনেক ধন্যবাদ .. এখন এটি স্পষ্ট: ডি
অ্যান্টিওকোস

6
অনুলিপি 3 অনুলিপি অনুলিপি পোস্টারদের জন্য:var arr = Int(repeating: Int(repeating: 0, count: 2), count: 3)
কর

1
var arr = Array(count: 2, repeatedValue: Array(count: 3, repeatedValue: 0))
সুইফটে

27

ডক্স থেকে:

স্কোয়ার ব্র্যাকেটের জোড় জোড় করে আপনি বহুমাত্রিক অ্যারে তৈরি করতে পারেন, যেখানে মৌলিক ধরণের উপাদানগুলির নামটি বর্গাকার বন্ধনীগুলির অন্তঃতম জোড়াতে অন্তর্ভুক্ত। উদাহরণস্বরূপ, আপনি তিনটি বর্গক্ষেত্র বন্ধনী ব্যবহার করে পূর্ণসংখ্যার একটি ত্রি-মাত্রিক অ্যারে তৈরি করতে পারেন:

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

বহুমাত্রিক অ্যারেতে উপাদানগুলি অ্যাক্সেস করার সময়, বাম-সর্বাধিক সাবস্ক্রিপ্ট সূচকটি বহিরাগত অ্যারেতে সেই সূচকের উপাদানটিকে বোঝায়। ডানদিকে পরবর্তী সাবস্ক্রিপ্ট সূচীটি অ্যারেতে থাকা সূচকের সেই উপাদানটিকে বোঝায় যা এক স্তরের নেস্টেড রয়েছে And ইত্যাদি। এর অর্থ হ'ল উপরের উদাহরণে অ্যারে 3 ডি [0] [[1, 2], [3, 4]], অ্যারে 3 ডি [0] [1] [3, 4], এবং অ্যারে 3 ডি [0] [1 ] [1] 4 মানকে বোঝায়।


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
}

হাই, আমরা কি "যে কোনও অবজেক্ট" প্রকারের সাথে এক্সটেনশন হিসাবে উন্নত করতে পারি?
অ্যান্টিওখোস

রেফারেন্স ধরণের সমস্যা সম্পর্কে ভাল পয়েন্ট। তবে কেন আপনি Array(repeating: {value}, could 80)চারদিকে ধনুর্বন্ধনী লিখছেন {value}? এটি বন্ধের একটি অ্যারে তৈরি করবে, তাই না?
ডানকান সি

অথবা {value}"কোনও রকমের ধরণের কোনও মান" (একটি রেফারেন্স টাইপ) এর জন্য মেটা-নোটেশন কি?
ডানকান সি

এই সমস্যার কারণে আমি বাগের সন্ধানে প্রায় এক ঘন্টা সময় কাটিয়েছি ...
ম্যাথিউস ওয়েবার


10

অ্যাপল নথির সাথে সাথে সুইফট ৪.১ এর জন্য আপনি এই স্ট্রাক্টটি খুব সহজেই 2 ডি অ্যারে তৈরি করতে ব্যবহার করতে পারেন:

লিঙ্ক: https://developer.apple.com/library/content/docamentation/Swift/Conceptual/Swift_Programming_Language/Subscriptts.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
আমি এটা পছন্দ করি. এটি সি পয়েন্টার পাটিগণিতকে স্মরণ করিয়ে দেয়। জেনারিকস ব্যবহার করে আবার লিখলে ভাল হয়, সুতরাং এটি কোনও ডাটা টাইপের দ্বিমাত্রিক অ্যারেগুলিতে প্রয়োগ হয়। এই বিষয়টির জন্য, আপনি অ্যারেগুলিকে কোনও স্বেচ্ছাচারিত মাত্রা তৈরি করতে এই পদ্ধতির ব্যবহার করতে পারেন।
ডানকান সি

1
@ ভাকাওয়ামা, শীতল, আপনার এন-ডাইমেনশনাল অ্যারে বাদে অ্যারে ব্যবহার করে এমন সমস্ত সমাধানের মতো একই সমস্যা রয়েছে 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.9 মিমি

বনাম

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 অ্যারে: 135 মিমি পূরণের জন্য গড় কার্যকর সময়

উভয় অ্যালগরিদমগুলি হ'ল (এন ^ 2), সুতরাং পরীক্ষার সময়গুলির মধ্যে পার্থক্যটি আমরা টেবিলটি আরম্ভ করার উপায়ের কারণে ঘটে।

পরিশেষে, আপনি সবচেয়ে খারাপটি করতে পারেন append()নতুন উপাদান যুক্ত করতে ব্যবহার করা। এটি আমার পরীক্ষাগুলিতে সবচেয়ে ধীর বলে প্রমাণিত হয়েছিল:

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

অ্যাপেন্ড (): 2.59s ব্যবহার করে 50x50 অ্যারে পূরণের গড় নির্বাহের সময়

উপসংহার

বহুমাত্রিক অ্যারেগুলি এড়িয়ে চলুন এবং কার্যকর করার গতি বিবেচনায় থাকলে সূচক দ্বারা অ্যাক্সেস ব্যবহার করুন। 1 ডি অ্যারেগুলি আরও পারফরম্যান্ট, তবে আপনার কোডটি বুঝতে কিছুটা শক্ত হতে পারে।

আমার গিটহাব রেপো থেকে ডেমো প্রকল্পটি ডাউনলোড করার পরে আপনি নিজেই পারফরম্যান্স পরীক্ষা চালাতে পারেন: 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)}
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.