簡體   English   中英

將結構數組轉換為字典數組,其值以字符串形式表示

[英]Convert an array of structs into array of dictionaries with values stated as strings

我不確定這是否可能! 但也許 Stackoverflow 社區可以提供幫助。

工作描述:我創建了一個結構數組[imageFileNames]來幫助我對一堆 jpg 文件進行排序、過濾和映射。 使用相同的結構數組,我想填充一個嵌套在集合視圖中的表視圖。 集合視圖將使用鍵輸入作為標簽,而表格視圖將使用這些值來填充表格視圖單元格。

例子: 在此處輸入圖像描述

問題:為了同時填充集合單元格和表格視圖,我想將其轉換為字典數組,但我不想將字典值作為結構體,而是將它們轉換為字符串。 在結構中使用 part 屬性來填充字典中的鍵。 下面我展示了我的結構構建、結構數組和我的理想目標。

大家可以幫我建立一個可以管理轉換的功能嗎?

結構:

struct imageFileNames {
    var scene: String
    var object: String
    var objectNumber: String
    var part: String
    var frame: String
    
    init(scene:String, object:String, objectNumber: String, part:String, frame:String){
        self.scene = scene
        self.object = object
        self.objectNumber = objectNumber
        self.part = part
        self.frame = frame
    }
}

當前的:

var notFinal: [imageFileNames] = 
    CloneAnimation_20200907.imageFileNames(scene: "scene01", object: "character", objectNumber: "1", part: "kneeRight", frame: "00.png"),
    CloneAnimation_20200907.imageFileNames(scene: "scene01", object: "character", objectNumber: "1", part: "lefteyelid", frame: "01.png"),
    CloneAnimation_20200907.imageFileNames(scene: "scene01", object: "character", objectNumber: "1", part: "lefteyelid", frame: "02.png"),
    CloneAnimation_20200907.imageFileNames(scene: "scene01", object: "character", objectNumber: "1", part: "lefteyelid", frame: "03.png"),
    CloneAnimation_20200907.imageFileNames(scene: "scene01", object: "character", objectNumber: "1", part: "lefteyelid", frame: "04.png"),
    CloneAnimation_20200907.imageFileNames(scene: "scene01", object: "character", objectNumber: "1", part: "lefteyelid", frame: "05.png"),
    CloneAnimation_20200907.imageFileNames(scene: "scene01", object: "character", objectNumber: "1", part: "mouthAngry", frame: "00.png"),
    CloneAnimation_20200907.imageFileNames(scene: "scene01", object: "character", objectNumber: "1", part: "mouthAngry", frame: "01.png"),
    CloneAnimation_20200907.imageFileNames(scene: "scene01", object: "character", objectNumber: "1", part: "mouthAngry", frame: "02.png"),
    CloneAnimation_20200907.imageFileNames(scene: "scene01", object: "character", objectNumber: "1", part: "mouthAngry", frame: "03.png"),
]

目標:

var goalFinal: [String: [String]] = [
    "lefteyelid": [
        "scene01_character_1_lefteyelid_01",
        "scene01_character_1_lefteyelid_02",
        "scene01_character_1_lefteyelid_03",
        "scene01_character_1_lefteyelid_04"
    ],
     "mouthAngry": [
        "scene01_character_1_mouthAngry_00",
        "scene01_character_1_mouthAngry_01",
        "scene01_character_1_mouthAngry_02",
        "scene01_character_1_mouthAngry_03",
    ]
]

我的嘗試:正如你從我的嘗試中看到的那樣,我對這件事很執着。

解析出鍵值:

  1. 我嘗試使用let dict = notFinal.toDictionary {$0.part}方法來解析鍵輸入並將相應的結構作為值放入數組中,但是這種方法不起作用,因為它只顯示帶有相同的零件名稱。

將結構轉換為字符串:

  1. 我能夠創建一個函數,該函數采用結構並將所有屬性組合成一個字符串,但沒有初始部分就毫無價值。
func convertStructIntoString (structHold: [imageFileNames])->[String] {
    var temp: [imageFileNames] = structHold
   
        let final = temp.map {$0.scene + "_" + $0.object + "_" + $0.objectNumber + "_" + $0.part + "_" + $0.frame}
    
    return final
}

在提供答案之前,讓我將您的類重命名為ImageFileName以使代碼更清晰易讀,因此我們得到了這個(您可能會考慮使用其他名稱,因為該結構似乎並不是一個文件名):

struct ImageFileName {
    var scene: String
    var object: String
    var objectNumber: String
    var part: String
    var frame: String
}

將類型名稱設為大寫可能是一個好主意,並且您提供的構造函數對於結構來說並不是真正需要的——它是自動生成的。

現在執行您正在尋找的轉換的函數將是:

func finalize(_ imageFileNames: [ImageFileName]) -> [String: [String]] {
    Dictionary(grouping: imageFileNames) { imageFileName in
        imageFileName.part
    }
    .mapValues { groupImageFileNames in
        groupImageFileNames.map { imageFileName in 
            "\(imageFileName.scene)_\(imageFileName.object)_\(imageFileName.part)_\(URL(string: imageFileName.frame)!.deletingPathExtension())"
        }
    }
}

或者,更簡潔的版本做同樣的事情:

func finalize(_ imageFileNames: [ImageFileName]) -> [String: [String]] {
    Dictionary(grouping: imageFileNames, by: { $0.part })
        .mapValues { $0.map { "\($0.scene)_\($0.object)_\($0.part)_\(URL(string: $0.frame)!.deletingPathExtension())" } }
}

所以你可以這樣做:

let notFinal: [ImageFileName] = [
    ImageFileName(scene: "scene01", object: "character", objectNumber: "1", part: "kneeRight", frame: "00.png"),
    ImageFileName(scene: "scene01", object: "character", objectNumber: "1", part: "lefteyelid", frame: "01.png"),
    ImageFileName(scene: "scene01", object: "character", objectNumber: "1", part: "lefteyelid", frame: "02.png"),
    ImageFileName(scene: "scene01", object: "character", objectNumber: "1", part: "lefteyelid", frame: "03.png"),
    ImageFileName(scene: "scene01", object: "character", objectNumber: "1", part: "lefteyelid", frame: "04.png"),
    ImageFileName(scene: "scene01", object: "character", objectNumber: "1", part: "lefteyelid", frame: "05.png"),
    ImageFileName(scene: "scene01", object: "character", objectNumber: "1", part: "mouthAngry", frame: "00.png"),
    ImageFileName(scene: "scene01", object: "character", objectNumber: "1", part: "mouthAngry", frame: "01.png"),
    ImageFileName(scene: "scene01", object: "character", objectNumber: "1", part: "mouthAngry", frame: "02.png"),
    ImageFileName(scene: "scene01", object: "character", objectNumber: "1", part: "mouthAngry", frame: "03.png")
]

let goalFinal = finalize(notFinal)

已編輯:修改finalized的函數以添加尾隨幀索引,正如@Jessy 指出的那樣

  1. 采用CustomStringConvertible

     import Foundation extension imageFileNames: CustomStringConvertible { var description: String { """ \(scene)_\(object)_\(objectNumber)_\(part)_\ \(URL(string: frame)!.deletingPathExtension()) """ } }
  2. 做其他人告訴你的事情:

     import struct Collections.OrderedDictionary extension OrderedDictionary where Key == String, Value == [String] { init(_ imageFileNamesSequence: some Sequence<imageFileNames>) { self = OrderedDictionary<_, _>(grouping: imageFileNamesSequence, by: \.part) .mapValues { $0.map(String.init) } } }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM