【问题标题】:Swift Collection extension: pick every other itemSwift Collection 扩展:选择其他所有项目
【发布时间】:2019-03-07 23:55:33
【问题描述】:

我在 Swift 中为 Collection 编写了以下扩展,它从起始索引返回每个其他元素的新 Collection。

extension Collection {
    func everyOtherElement(from theIndex: Int = 0) -> [Element]  {
        if theIndex >= self.count { return self as! [Element] }

        let start = self.index(startIndex, offsetBy: theIndex)
        let end = self.endIndex
        var everyOther = [Element]()
        var iter = start

        while iter != end {
            everyOther.append(self[iter])
            let next = index(after: iter)
            if next == end { break }
            iter = index(after: next)
        }       
                 return everyOther
        }
}

可能有改进代码的方法,但我的问题是当集合是字典时。该扩展有效,但返回一个元组数组 [(key: key, value: value)] 我希望扩展返回字典。

我已经尝试过 Dictionary(uniqueKeysWithValuesMethod) ,它一旦应用于everyOtherElement 方法的返回就可以正常工作,但我似乎无法找到直接实现它的方法。

var myDictionary =  ["EN" : "Cheers", "SV" : "Skåll", "ES" : "Salud" ].everyOtherElement()
// returns [(key: "EN", value: "Cheers"),(key: "ES", value: "Salud")]

Dictionary(uniqueKeysWithValues: myDictionary.map { ($0.key, $0.value)})
// returns ["EN" : "Cheers", "ES" : "Salud" ]

感谢您的帮助!

【问题讨论】:

  • 你的函数做不同的事情。您快进到给定的索引,然后删除所有其他项目。在字典的上下文中,这两个部分都没有意义,字典没有定义。
  • self as! [Element] 您不能强制将所有集合转换为元素数组。不等于Array<Characters> 的字符串
  • 你明确返回一个数组
  • 感谢大家抽空回复!!!我确实返回了一个数组[Element],因为我没有找到任何其他编译方式。因此我最初的问题是:换句话说,如果可能的话,我如何更改代码以便它也适用于字典!

标签: swift dictionary collections


【解决方案1】:

正如其他人提到的,字典是一个无序的集合。如果你想返回一个字典,你可以简单地扩展字典并过滤所有其他元素。请注意,不能保证字典将保持键值对输入的顺序。话虽这么说,你可以完成你想要的如下:

extension Dictionary {
    var everyOtherElements: Dictionary {
        var bool = true
        return filter { _ in
            defer { bool = !bool }
            return bool
        }
    }
}

let dict =  ["EN" : "Cheers", "SV" : "Skåll", "ES" : "Salud" ]
// returns [(key: "EN",
let everyOtherElements = dict.everyOtherElements  // ["ES": "Salud", "SV": "Skåll"]

关于你的评论

从您的回复中了解到,我无法扩展所有收藏 相同的代码,我需要按类型分解吗?

您不需要扩展每个元素类型,例如,您可以扩展 RangeReplaceableCollection 协议并返回 Self,这也将覆盖 Strings:

extension RangeReplaceableCollection  {
    mutating func removeEvenIndexElements() {
        var bool = true
        removeAll { _ in
            defer { bool = !bool }
            return bool
        }
    }
    mutating func removeOddIndexElements() {
        var bool = false
        removeAll { _ in
            defer { bool = !bool }
            return bool
        }
    }
    func evenIndexElements() -> Self {
        var bool = true
        return filter { _ in
            defer { bool = !bool }
            return bool
        }
    }
    func oddIndexElements() -> Self {
        var bool = false
        return filter { _ in
            defer { bool = !bool }
            return bool
        }
    }
}

var alphabet = "abcdefghijklmnopqrstuvwxyz"
alphabet.removeEvenIndexElements()
alphabet   // "bdfhjlnprtvxz"

var arr = [1,2,3,4,5,6,7,8,9,0]
arr.removeOddIndexElements()
arr        //  [1, 3, 5, 7, 9]

【讨论】:

  • 谢谢利奥!我从您的回复中了解到,我无法使用相同的代码扩展所有集合,我需要按类型分解它(?)。
猜你喜欢
  • 1970-01-01
  • 2012-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多