Swift -将数组转换为多维数组

kq0g1dla  于 2022-11-28  发布在  Swift
关注(0)|答案(2)|浏览(164)

以下是阵列型号:

struct UserModel: Codable {
    var userid: Int
    var nickname: String
}

struct UserModelSplit: Codable {
    var usr: [UserModel]
}

初始化:

@State private var users = [UserModel]()
@State private var userSplit = [UserModelSplit]()

获取第一个数组:

for bla in userReceived{
    users.append(UserModel(userid: bla.userid, nickname: bla.nickname))
}

现在我想将其拆分为多维数组,因此结果应为:

userSplit[0][0] // 1th user
userSplit[0][1] // 2th user
userSplit[0][2] // 3th user
userSplit[0][3] // 4th user
userSplit[1][0] // 5th user
userSplit[1][1] // 6th user
userSplit[1][2] // 7th user
userSplit[1][3] // 8th user

我尝试了所有类型的语法,并查找如何可以做到这一点,没有发现任何有用的。
下面是我尝试过的伪代码:

var current = 0
var added = 0
for val in users{
    userSplit[current][added] = val
    
    added += 1
    if(added == 3){
        current += 1
        added = 0
    }
}

这个伪代码类似于它在PHP中的实际工作方式
我希望这是可以理解的:D

ee7vknir

ee7vknir1#

你真的很接近了,要制作一个二维阵列,你可以这样做。

struct UserModel: Codable {
    var userid: Int
    var nickname: String
}

var users : [UserModel] = (1...20).map({ n in
    UserModel(userid: n, nickname: UUID().uuidString)
})

//Change this number to make the sub arrays the size that you want.
let size = 3

//User Split as a 2D Array
var userSplit : [[UserModel]] = stride(from: 0, to: users.count, by: size).map {
    users[$0 ..< Swift.min($0 + size, users.count)].map{$0}
}

for splitIdx in userSplit.indices{
    print(splitIdx)
    for userIdx in userSplit[splitIdx].indices {
        print(userSplit[splitIdx][userIdx])
    }
}

使用您拥有的另一个模型,它应该是这样的...

struct UserModelSplit: Codable {
    var usr: [UserModel]
}
//Array<UserModelSplit>   NOT 2D Array
var userSplit : [UserModelSplit] = stride(from: 0, to: users.count, by: size).map {
    UserModelSplit(usr: users[$0 ..< Swift.min($0 + size, users.count)].map{$0})
}

for splitIdx in userSplit.indices{
    print(splitIdx)
    for userIdx in userSplit[splitIdx].usr.indices {
        print(userSplit[splitIdx].usr[userIdx])
    }
}

在这两种情况下,您将得到类似于以下内容的打印输出

你的代码不能工作的最大原因是因为在swift中你只能使用

array[index] = something

若要替换现有值,请执行以下操作。
你必须

array.append(something)

创建新索引时,请使用此选项。
您可以使用Arrayextension将任何数组拆分为二维数组

extension Array {
    func split(_ size: Int) -> [[Element]] {
        return stride(from: 0, to: count, by: size).map {
            Array(self[$0 ..< Swift.min($0 + size, count)])
        }
    }
}

然后使用

//User Split as a 2D Array
var userSplit : [[UserModel]] = users.split(size)
ffscu2ro

ffscu2ro2#

您可以使用sequence方法来逐一查看集合,并将每个子序列初始化成其元素的新集合:

extension Collection {
    var quadruplets: [[Element]] {
        .init(
            sequence(state: startIndex) { start in
                guard start < endIndex else { return nil }
                let end = index(start, offsetBy: 4, limitedBy: endIndex) ?? endIndex
                defer { start = end }
                return .init(self[start..<end])
            }
        )
    }
}

用法:

struct UserModel: Codable {
    let userid: Int
    let nickname: String
}

let users = [
    (1,"a"),
    (2,"b"),
    (3,"c"),
    (4,"d"),
    (5,"e"),
    (6,"f"),
    (7,"g"),
    (8,"h"),
    (9,"i"),
    (10,"j"),
].map(UserModel.init)

let userSplit = users.quadruplets

userSplit[0][0].nickname  // "a"
userSplit[0][1].nickname  // "b"
userSplit[0][2].nickname  // "c"
userSplit[0][3].nickname  // "d"
userSplit[1][0].nickname  // "e"
userSplit[1][1].nickname  // "f"
userSplit[1][2].nickname  // "g"
userSplit[1][3].nickname  // "h"
userSplit[2][0].nickname  // "i"
userSplit[2][1].nickname  // "j"

编辑/更新

如果你不想重复集合元素,你可以只迭代原始集合子序列。

extension Collection {
    func unfoldSubSequences(limitedTo maxLength: Int) -> UnfoldSequence<SubSequence,Index> {
        sequence(state: startIndex) { start in
            guard start < endIndex else { return nil }
            let end = index(start, offsetBy: maxLength, limitedBy: endIndex) ?? endIndex
            defer { start = end }
            return self[start..<end]
        }
    }
    func subSequences(limitedTo maxLength: Int) -> [SubSequence] { .init(unfoldSubSequences(limitedTo: maxLength))
    }
}

用法:

let subSequences = users.subSequences(limitedTo: 4)

subSequences[0][0].nickname  // "a"
subSequences[0][1].nickname  // "b"
subSequences[0][2].nickname  // "c"
subSequences[0][3].nickname  // "d"
subSequences[1][4].nickname  // "e"
subSequences[1][5].nickname  // "f"
subSequences[1][6].nickname  // "g"
subSequences[1][7].nickname  // "h"
subSequences[2][8].nickname  // "i"
subSequences[2][9].nickname  // "j"

for subsequence in subSequences {
    for user in subsequence {
        print(user)
    }
}

这将打印
用户模型(用户ID:1、昵称:“一”)
用户模型(用户ID:2、昵称:“B”)
用户模型(用户ID:3、昵称:“c”)
用户模型(用户ID:4、昵称:“d”)
用户模型(用户ID:5、昵称:“e”)
用户模型(用户ID:6、昵称:“f”)
用户模型(用户ID:7、昵称:“g”)
用户模型(用户ID:8、昵称:“h”)
用户模型(用户ID:9、昵称:“i”)
用户模型(用户ID:10、绰号:“j”)
为了使它完整,你可以扩展RangeReplaceableCollection,如下所示。这也适用于字符串(字符集合):

extension RangeReplaceableCollection {
    func groups(limitedTo maxLength: Int) -> [Self] {
        subSequences(limitedTo: maxLength).map(Self.init)
    }
}

let quadruplets = "abcdefghij".groups(limitedTo: 4)

quadruplets[0]  // "abcd"
quadruplets[1]  // "efgh"
quadruplets[2]  // "ij"

相关问题