【问题标题】:Create multidimensional array based on value of key根据键的值创建多维数组
【发布时间】:2019-01-30 12:47:53
【问题描述】:

我有一个arrayMyData 对象(MyData 是一个struct):

[
MyData(id: 3, locale: "en", title: "p1", date: "10/15/2019"), 
MyData(id: 3, locale: "de", title: "p2", date: "11/12/2019"), 
MyData(id: 32, locale: "fr", title: "free", date: "10/11/2019"), 
MyData(id: 15, locale: "de", title: "free", date: "10/11/2019"), 
MyData(id: 19, locale: "de", title: "p1", date: "11/10/2019"),
MyData(id: 19, locale: "de", title: "p2", date: "11/10/2019"),
MyData(id: 19, locale: "de", title: "p3", date: "11/10/2019"),
]

我想根据id 键对这个数组进行分组(甚至故意创建一个新数组)。

结果应该是这样的:

[
[MyData(id: 3, locale: "en", title: "p1", date: "10/15/2019"), MyData(id: 3, locale: "de", title: "p2", date: "11/12/2019")], 
MyData(id: 32, locale: "fr", title: "free", date: "10/11/2019"), 
MyData(id: 15, locale: "de", title: "free", date: "10/11/2019"), 
[MyData(id: 19, locale: "de", title: "p1", date: "11/10/2019"),MyData(id: 19, locale: "de", title: "p2", date: "11/10/2019"),MyData(id: 19, locale: "de", title: "p3", date: "11/10/2019")]
]

即:具有相同id的数组应该组成一个新数组。

当然,我可以简单地循环第一个数组并创建第二个数组,但我想知道 Swift 是否可以用它的过滤器做些什么。 任何帮助表示赞赏。

【问题讨论】:

  • 离题,不建议将结构命名为Data
  • 你不是跑题,别担心,这是一个明智的建议:我的结构的真实名称甚至不是数据,我在这里写数据是为了帮助人们更好地理解这个问题。我将其更改为 MyData

标签: arrays swift sorting


【解决方案1】:

您当然可以在此使用高阶函数,但不能 100% 完全产生所需的结果,而是其中的一大部分,因为您所需的数组类型是 :[Any]

查看以下代码:

var myGroup = Dictionary(grouping: arrayOne, by: { $0.id }) // group each element by id -type of: [Int:[Data]]
let resultArray = myGroup.map { $0.value } //map out the elements without the id key. -type of: [[Data]]

//Create hetro Array so we can use it later to append the results
var myHetroArray: [Any] = []
// loop each array in the result array and check if it only contains 1 element if so append that one element to the hetro array otherwise just append the whole thing.
for array in resultArray {
    if array.count ==  1 {
    myHetroArray.append(array.first!)
    } else {
        myHetroArray.append(array)
    }
}

print(myHetroArray) // produce the desired result.

输出: [
[数据(id:19,语言环境:“de”,标题:“p1”,日期:“11/10/2019”),数据(id:19,语言环境:“de”,标题:“p2”,日期: "11/10/2019"),Data(id: 19, locale: "de", title: "p3", date: "11/10/2019")],
数据(id:15,语言环境:“de”,标题:“free”,日期:“10/11/2019”),
数据(id:32,语言环境:“fr”,标题:“free”,日期:“10/11/2019”),
[数据(id:3,语言环境:“en”,标题:“p1”,日期:“10/15/2019”),数据(id:3,语言环境:“de”,标题:“p2”,日期: “2019 年 11 月 12 日”)]
]

【讨论】:

  • 没关系。我并不惊讶没有更好的方法来做到这一点,但这并不重要,因为无论如何它解决了服务器数据问题(无法更改的 JSON)
  • 好吧,如果我有什么新的想法,我会编辑答案,但我想即使使用高阶函数,你也无法生成异构类型数组
【解决方案2】:

还有两种方法。就像这里的注释一样。

    struct MyData{
        let id : Int
        let locale : String
        let title : String
        let date : String
    }

    let data = [
        MyData(id: 3, locale: "en", title: "p1", date: "10/15/2019"),
        MyData(id: 3, locale: "de", title: "p2", date: "11/12/2019"),
        MyData(id: 32, locale: "fr", title: "free", date: "10/11/2019"),
        MyData(id: 15, locale: "de", title: "free", date: "10/11/2019"),
        MyData(id: 19, locale: "de", title: "p1", date: "11/10/2019"),
        MyData(id: 19, locale: "de", title: "p2", date: "11/10/2019"),
        MyData(id: 19, locale: "de", title: "p3", date: "11/10/2019"),
    ]


    data.reduce(into: [:]) { ( result, next) in
    if result.keys.contains(next.id){
        (result[next.id] as? [MyData]).map{result[next.id] =  $0 + [next] }
        ([result[next.id]] as? [MyData]).map{result[next.id] = $0 + [next]}
    }
    else{ result[next.id] = next }
}.values


    Set(data.map{$0.id}).map{id -> Any in
        let result = data.filter{$0.id == id}
        return result.count == 1 ? result.first! : result
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-27
    • 1970-01-01
    • 2018-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多