将[[(Int,String)]]组合成[(Int,String)]的优雅方法?

时间:2017-12-04 04:19:17

标签: ios swift4 xcode9

我使用的是Swift 4,Xcode 9。

具体来说,我有一个数组[[(Int,String)]]数组,其中Int是一个排名,String是一个名称+项目......使用.joined组合(分隔符:&#34 ;;& #34;。)

数据可能如下所示:

[[1,"My Name;Item1;Item2"], [(5,"My Name;Item2;Item3"), (3,"My Second Name;Item1")]]

我想组合内部数组,以便:

  1. Int根据名称添加匹配项目(最多为";")
  2. 字符串添加后续项目(如果尚未存在)
  3. 结合我上面的例子应该导致:

    [(6,"My Name;Item1;Item2;Item3"), (3,"My Second Name;Item1")]
    

    即。输入为[[(Int, String)]],输出为[(Int, String)]

    目前,我可以通过一组相当复杂的循环来实现这一目标。使用大型数据集,会导致性能显着下降。在我请求时,是否有一种优雅/简单的方法来组合这些数组?

    感谢您的指导!

1 个答案:

答案 0 :(得分:3)

(一般情况下,我会将此作为评论,因为它没有回答这个问题,但确切地说明你应该如何改变这个问题是值得的。)

这当然是可能的,但不是。答案是用一组结构替换它。根据您的数据描述:

struct Element {
    let rank: Int
    let name: String
    let items: Set<String> // Since you seem to want them to be unique and unordered
}

let elements: [[Element]] =
    [[Element(rank: 1, name: "My Name", items: ["Item1", "Item2"])],
     [Element(rank: 5, name: "My Name", items: ["Item2", "Item3"]),
      Element(rank: 3, name: "My Second Name", items: ["Item1"])]]

// You want to manage these by name, so let's make key/value pairs of all the elements
// as (Name, Element)
let namedElements = elements.joined().map { ($0.name, $0) }

// Now combine them as you describe. Add the ranks, and merge the items
let uniqueElements =
    Dictionary<String, Element>(namedElements,
                                uniquingKeysWith: { (lhs, rhs) -> Element in
                                    return Element(rank: lhs.rank + rhs.rank,
                                                   name: lhs.name,
                                                   items: lhs.items.union(rhs.items))
    })

// The result is the values of the dictionary
let result = uniqueElements.values

// Element(rank: 6, name: "My Name", items: Set(["Item3", "Item2", "Item1"]))
// Element(rank: 3, name: "My Second Name", items: Set(["Item1"]))