我有一种情况,我需要连接两个数组,这两个数组通常有一个重叠的子array.

如果我有:

let input1 = ["A", "B", "F", "E"]

let input2 = ["F", "E", "A", "G"]

结果应该是:

let result = ["A", "B", "F", "E", "A", "G"]

So it's a bit like a "union" in the sense that the output does not duplicate the shared subarray/intersection 和 contains both arrays in their original state (just overlapping/intersecting). The canonical way to do something similar is with Sets, but that would remove the second "A".

推荐答案

为了好玩,您可以在从结尾开始迭代第一个序列时使用start with predicate,如下所示:

let first: [String] = ["A", "B", "F", "E"]
let second: [String] = ["F", "E", "A", "G"]

var pos = first.endIndex
while pos > first.startIndex,
      second.starts(with: first[pos...], by: { $0 != $1}),
      !second.isEmpty {
    first.formIndex(before: &pos)
}

let result = first[..<pos] + second // ["A", "B", "F", "E", "A", "G"] 

这将产生一个子序列,在本例中是一个数组切片.如果需要数组,只需显式设置结果类型:

let result: [String] = first[..<pos] + second

根据OP注释,如果需要成对匹配子序列,只需每隔两个元素进行偏移:

let first = "ABFF"
let second = "FFAG"

var pos = first.endIndex
while pos > first.startIndex,
      second.starts(with: first[pos...], by: { $0 != $1 }),
      !second.isEmpty {
    first.formIndex(&pos, offsetBy: -2)
}

let result: String = first[..<pos] + second  // "ABFFAG"

如果需要用空格分隔的字符串元素:

var first = "A B C D E F G D E"
var second = "D E F C B A"

first.removeAll(where: \.isWhitespace)
second.removeAll(where: \.isWhitespace)

var pos = first.endIndex
while pos > first.startIndex,
      second.starts(with: first[pos...], by: { $0 != $1 }),
      !second.isEmpty {
    first.formIndex(&pos, offsetBy: -2)
}

let result = (first[..<pos] + second)
                 .map(String.init)
                 .joined(separator: " ")
result  // "A B C D E F G D E F C B A"

编辑/更新:

按照上一次 comments /回答中显示的逻辑,您可以执行以下操作:

extension RangeReplaceableCollection where Element: Equatable {
    mutating func appendAndMerge<C: Collection>(with collection: C) where C.Element == Element {
        var lowerBound = startIndex
        formIndex(&lowerBound, offsetBy: Swift.min(count, count-collection.count), limitedBy: endIndex)
        while !collection.starts(with: self[lowerBound...]) {
            formIndex(&lowerBound, offsetBy: 1, limitedBy: endIndex)
        }
        replaceSubrange(lowerBound..., with: collection)
    }
}

用法:

var first = ["at", "by", "chicken", "dog", "eat", "for", "good", "dog", "eat"]
let second =  ["good", "dog", "eat", "feed", "cats", "bonk", "atrophe"]
first.appendAndMerge(with: second)
print(first)

这会打印出来

["at","by","chicken","dog","eat","for","good","dog","eat","feed","cats","bonk","atrophy"]


使用字符串(字符集合)

var first = "at by chicken dog eat for good dog eat"
let second =  "good dog eat feed cats bonk atrophe"
first.appendAndMerge(with: second)
print(first)

这会打印出来:

"由鸡、狗、吃为好、狗、吃为食、cat 、邦克阿托弗"

Swift相关问答推荐

当我点击模拟器中的文本字段时,UIKit CLLocationButton崩溃

字符串目录不适用于SWIFT包

避免嵌套导航TabView

可选,类似于自定义类型的初始化

Swift图表';chartXVisibleDomain挂起或崩溃

为什么这个快速代码不显示文本字段?

ClosedRange.Swift 中 Int 的索引?

计算 CoreData 中所有唯一对象的数量?

SwiftUI 中的同一个 ForEach 中是否可以有 2 个数组?

如何从 RC 加载场景作为 ModelEntity 而不是普通实体?

如何在 swift 5.0 中获取当前行

如何将视图添加到多行文本视图的末尾?

如何使 SwiftUI Picker 换行文本

如何在界面生成器中创建 UILayoutGuide?

使用 phimagemanager 将图像保存到自定义相册?

在 Swift 中以编程方式更新约束的常量属性?

WKWebView 确实从本地文档文件夹加载资源

Swift中方法的弃用和其他属性,如何?

如何快速将弹出框调整为表格视图中内容的大小?

如何快速格式化用户显示(社交网络等)的时间间隔?