【问题标题】:Combine two loops into one将两个循环合二为一
【发布时间】:2016-07-10 01:41:44
【问题描述】:

此代码用于按首字母对字符串数组进行分组。

//plain array
var list = ["apple", "apricot", "banana", "blackberry"]

//dictionary of arrays
var dict = Dictionary<String, Array<String>>()

//create necessary keys from first characters
for word in list {
    dict[ String( word.characters.prefix(1) ) ] = [ ]
}

//add words to the key of their first character
for word in list {
    dict[ String( word.characters.prefix(1) ) ]?.append( word )
}

//output dictionary
print(dict)

这个例子会输出这样的字典:

[ "b": ["ba", "bb"],
  "a": ["aa", "ab"] ]

代码有两个相似的for 循环。它们可以组合成一个循环而不影响输出吗?

【问题讨论】:

    标签: arrays swift loops dictionary optimization


    【解决方案1】:

    对于groupBy 函数来说,这听起来很完美:

    extension Array {
        func groupBy<T: Hashable>(f: Element -> T) -> [T: [Element]] {
            var results = [T: [Element]]()
            for element in self {
                let key = f(element)
                if results[key] != nil {
                    results[key]!.append(element)
                } else {
                    results[key] = [element]
                }
            }
            return results
        }
    }
    
    var list = ["apple", "apricot", "banana", "blackberry"]
    let dict = list.groupBy {
        String($0.characters.prefix(1))
    }
    

    让我们一步一步来:

    • groupBy 采用一个函数,该函数为数组的每个元素提供一个键。它返回一个包含键的字典和具有相同键的元素列表。
    • f 就是那个按键功能。对于数组中的每个元素,检查结果字典是否已经具有该键。如果是,它将被附加到该键的元素列表中。如果不是,它会为该键创建一个新数组。

    【讨论】:

    • 这是有道理的。我没有想到groupBy。所以该函数只需要在添加 an 元素之前检查键是否已经创建。
    • 是否可以保留键的顺序?
    • 字典没有顺序。获取键列表,对它们进行排序,然后按该顺序遍历字典
    【解决方案2】:
        //plain array
        let list = ["apple", "apricot", "banana", "blackberry"]
    
        //dictionary of arrays
        var dict = Dictionary<String, Array<String>>()
    
        //create necessary keys from first characters
        for word in list {
    
            if let _ = dict[ String( word.characters.prefix(1) )] {
                dict[ String( word.characters.prefix(1) )]?.append(word)
            }
            else{
                dict[ String( word.characters.prefix(1) ) ] = [word]
            }
        }
    
        //output dictionary
        print(dict)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多