小编Tim*_*qua的帖子

在Swift中,一个有效的函数,它根据谓词将数组分成2个数组

注意:我目前仍在使用Swift 2.2,但也对Swift 3解决方案开放

我正在寻找创建一个非常接近的函数filter,除了它保持不匹配的结果,并维护排序顺序.例如,假设您想过滤掉数组中可被3整除的数字,并且仍然保留不能被3整除的数字列表.


选项1:使用 filter

使用filter,您只能得到可被3整除的数字列表,原始列表保持不变.然后,您可以使用相反的谓词再次过滤原始列表,但这是不必要的第二遍.代码如下所示:

let numbers = [1,2,3,4,5,6,7,8,9,10]
let divisibleBy3 = numbers.filter { $0 % 3 == 0 } // [3,6,9]
let theRest = numbers.filter { $0 % 3 != 0 }      // [1,2,4,5,7,8,10]
Run Code Online (Sandbox Code Playgroud)

确实,这是非常可读的,但是对于我而言,它执行2遍的事实似乎效率低下,特别是如果谓词更复杂的话.这是实际需要的两倍多的检查.

选项2:separateCollection扩展中使用自定义功能

我的下一次尝试是扩展Collection并制作一个我打电话的功能separate.此函数将获取集合并一次一个地浏览元素,并将它们添加到匹配列表或不匹配列表中.代码如下所示:

extension Collection {
    func separate(predicate: (Generator.Element) -> Bool) -> (matching: [Generator.Element], notMatching: [Generator.Element]) {
        var groups: ([Generator.Element],[Generator.Element]) = ([],[])
        for element in self {
            if predicate(element) {
                groups.0.append(element) …
Run Code Online (Sandbox Code Playgroud)

arrays swift

16
推荐指数
4
解决办法
3492
查看次数

创建表示可以打开或关闭的可打包对象的协议

我正在尝试创建一个简单的协议,说明对象是处于"开启"状态还是"关闭"状态.对此的解释取决于实施对象.对于a UISwitch,无论开关是打开还是关闭(duh).对于a UIButton,可能是按钮是否处于selected状态.对于a Car,可能是汽车的引擎是否打开,或者即使它是否在移动.所以我开始创建这个简单的协议:

protocol OnOffRepresentable {
    func isInOnState() -> Bool
    func isInOffState() -> Bool
}
Run Code Online (Sandbox Code Playgroud)

现在我可以扩展前面提到的UI控件,如下所示:

extension UISwitch: OnOffRepresentable {
    func isInOnState() -> Bool { return on }
    func isInOffState() -> Bool { return !on }
}

extension UIButton: OnOffRepresentable {
    func isInOnState() -> Bool { return selected }
    func isInOffState() -> Bool { return !selected }
}
Run Code Online (Sandbox Code Playgroud)

现在我可以创建这些类型的对象的数组并循环它,检查它们是打开还是关闭:

let booleanControls: [OnOffRepresentable] = [UISwitch(), UIButton()]
booleanControls.forEach { print($0.isInOnState()) }
Run Code Online (Sandbox Code Playgroud)

大!现在我想创建一个将这些控件映射到a的字典,UILabel以便在控件更改状态时更改与控件关联的标签的文本.所以我去宣布我的字典:

var toggleToLabelMapper: …
Run Code Online (Sandbox Code Playgroud)

protocols type-erasure ios hashable swift

10
推荐指数
1
解决办法
2574
查看次数

在Swift中,如何防止在子类上调用函数?

我有一个基类,它在一些数据结构中存储了很多其他数据对象,这个类通过一组add/ remove函数来管理我的集合中的那些数据对象,这些/ 函数使我的数据结构保持同步.

现在我去子类这个基类,子类就像基类一样,除了它对它将接受什么类型的数据对象有特殊规则(它查看数据对象上的值,如果值,则拒绝它们)不对.)由于这种"有效性"检查,我为被调用的子类创建了一个新函数change.在该change函数中,它检查所有传入的数据对象并验证它们是否正常,并用这些数据对象替换数据结构中的所有数据对象.

问题是我不希望有人能够创建子类对象并允许它们调用基类add/ remove函数,因为我只希望子类能够通过子类的change函数进行更改.

我还没有找到一种很好的方法来"禁用"子类中这些基类函数的使用.我可以override使用函数并实现空实现,但是没有反馈给调用者该函数没有做任何事情.如果我使用类似的东西fatalError,它不是编译时间,它是运行时.

我的另一个想法是将基类的功能分解为多个协议,并将基类更改为简单地拥有所有数据结构,但是不符合任何协议,然后有多个子类,其中需要该add功能的子类可以继承自基础并且另外符合add协议,但是不希望addremove可以从基础继承的协议,并且根本不符合任何协议,而是创建它们自己的change函数来修改数据结构.

这是一个更简单的层次结构来解释:

class Parent {

  func doThis() { print("Parent Did This") }
  func doThat() { print("Parent Did That") }

}

class Child: Parent {

  override func doThis() {
    print("Child Did This")
  }

  // I want this to be a compile time error
  override func doThat() {
    print("Not …
Run Code Online (Sandbox Code Playgroud)

inheritance ios swift

6
推荐指数
2
解决办法
4300
查看次数

在Swift中,有没有更好的方法来初始化"get"唯一变量?

假设我有一个类,MyClass它可以处于有效或无效状态.所以我用一个叫做的bool跟踪这个isValid.我想要初始化此值,false直到initialize调用类的函数.的initialize(和对应的reset功能)将直接能够改变的值isValid布尔.这是我到目前为止所建立的:

class MyClass {

  private var _isValid: Bool = false
  var isValid: Bool {
    get { return _isValid }
  }

// any required init functions

  func initialize() {
    // init stuff
    _isValid = true
  }

  func reset() {
    // reset stuff
    _isValid = false
  }

}
Run Code Online (Sandbox Code Playgroud)

那么这是最好的方法吗,或者有什么方法可以删除第二个私有var并以某种方式只允许类函数修改只读公共面向变量?

accessor ios swift

5
推荐指数
1
解决办法
2595
查看次数

使用枚举的默认值作为字典键而不显式转换为String

如果我宣布enum这样的话:

enum Keys {
    case key_one
    case key_two
}
Run Code Online (Sandbox Code Playgroud)

我可以打印它,它会自动转换为String:

print(Keys.key_one) // prints "key_one"
Run Code Online (Sandbox Code Playgroud)

如果我然后制作一个映射Strings到任何地方的字典(但Strings为了简单起见让我们再次选择),我认为它应该能够通过使用键来添加一个Keys.key_one键,对吧?错误.

var myDict = [String : String]()

/// error: cannot subscript a value of type '[String : String]' with an index
/// of type 'Keys'
myDict[Keys.key_one] = "firstKey"
Run Code Online (Sandbox Code Playgroud)

如果我明确转换Keys.key_one为这样的话,我可以这样做String:

myDict[String(Keys.key_one)] = "firstKey"
print(myDict) // ["key_one": "firstKey"]
Run Code Online (Sandbox Code Playgroud)

所以,我想这样做,而不必换我enumString()每一次.

我已经做了尝试了几件事情extension的关闭Dictionary使用where与关键字Key,并试图实现新subscript的功能,但我不能得到它的工作.有什么诀窍? …

enums dictionary key swift

5
推荐指数
1
解决办法
3522
查看次数

在Xcode调试控制台中打印多行字符串

我为基于Swift的iOS应用程序构建了一个基本的树数据结构,并且希望能够将其打印到控制台以进行调试。因此,我编写了一个函数,该函数将遍历树(预排序)并根据树中节点的深度在其自己的行上打印出每个节点的值,并在其之前插入许多选项卡。通过在代码中的某处调用该函数,在调试控制台中,它将显示如下:

root
    node1
        node1_1
        node1_2
    node2
        node2_1
            node2_1_1
        node2_2
    node3
        node3_1
Run Code Online (Sandbox Code Playgroud)

很好,它允许我只printInfo()在代码中的重要位置进行调用,但是我很快意识到我需要能够像在断点处暂停时那样在现场打印String值。因此,我创建了一个计算属性infoString,该属性将使用所有换行符从树中构建字符串(\n)和制表)\t以为我可以在断点处将其打印在调试控制台中。

我使用命令进行了尝试po infoString,但输出到控制台的内容是:"root\n\tnode1\n\t\tnode1_1\n\t\tnode1_2\n\tnode2\n\t\tnode2_1\n\t\t\tnode2_1_1\n\t\tnode2_2\n\tnode3\n\t\tnode3_1",这在技术上是正确的,因为这就是String的含义,但是我想实际看到换行符和选项卡。

那么,如何打印我的String以便看到换行符和选项卡?

console xcode multiline ios

4
推荐指数
1
解决办法
754
查看次数

在Xcode中,如何在Storyboard中重命名约束?

我正在使用Xcode中的Storyboard,并且我将一个Label添加到我正在处理的视图控制器中.由于我尝试使用我的所有应用程序使用自动布局,我的第一反应是向Label添加自动布局约束.所以我在Label所在的超级视图的顶部和左边添加了2个约束.我还为标签本身添加了Width和Height的约束,我知道我可以修改约束的值然后将它们设置为我希望他们成为什么样的人.我的故事板看起来像这样:

标签有4个约束

然后我意识到我忘记将标签的名称更改为更具描述性的内容.由于这是我的主视图的标题标签,我将标签重命名为"标题",并将顶级视图重命名为"MainView".所以现在我的故事板看起来像这样:

带有约束的MainView中的标题

然后我意识到我的约束仍然引用"标签"和"视图",所以我去重命名它们.我突出显示了Width的约束,按下enter并获得了一个编辑文本字段,并将"Label"替换为"Title"并再次按Enter键.编辑文本字段已关闭,但约束名称返回为"标签"而不是像我键入的"标题".我再次尝试,同样的结果.我尝试了高度约束,同样的结果.它不会让我更改约束的名称.所以我删除了Width约束并重新制作了Width约束.现在它有正确的名称引用"标题"而不是"标签".但是我不想删除约束并在每次更改约束所绑定的UI元素的名称时重新创建它.

在更改约束所绑定的元素的名称后,有没有办法重命名约束?

xcode constraints ios xcode-storyboard

2
推荐指数
1
解决办法
2097
查看次数

有没有更好的方法来比较两个排序的数组?

在Swift中,我有两个数组,我从最大到最小排序,这意味着数组的值是Comparable.我想定义一种自定义方式来比较两个数组,以便说一个是"小于"另一个.具有较少元素的数组总是小于较大的数组.我提出的工作得很好,但<操作员看起来太笨重了.它只是感觉应该有一些方法来浓缩它,或者有一个内置函数或内置函数的组合,将实现我想要的.这就是我所拥有的:

func <<T where T: Comparable>(lhs: [T], rhs: [T]) -> Bool {
  if lhs.count < rhs.count {
    return true
  }

  for i in 0..<lhs.count {
    if lhs[i] > rhs[i] {
      return false
    }
  }

  return true
}

let first = [9, 8, 7, 6, 4]
let second = [9, 8, 7, 6, 5]
let third = [8, 7, 6, 5, 4]
let fourth = [9, 8, 7, 6]

let firstSecondComp: Bool = first < second   // …
Run Code Online (Sandbox Code Playgroud)

arrays comparison swift

0
推荐指数
1
解决办法
274
查看次数