如何在数组中查找重复元素?我有一个电话号码的数组, 我需要从右到左搜索电话号码, 并找到相似的6个数字。然后将它们打印出来。
要查找重复项,可以通过电话号码建立交叉引用,然后将其缩小到仅包含重复项。例如:
let contacts = [
Contact(name: "Rob", phone: "555-1111"),
Contact(name: "Richard", phone: "555-2222"),
Contact(name: "Rachel", phone: "555-1111"),
Contact(name: "Loren", phone: "555-2222"),
Contact(name: "Mary", phone: "555-3333"),
Contact(name: "Susie", phone: "555-2222")
]
您可以使用以下方法构建交叉引用字典:
let crossReference = Dictionary(grouping: contacts, by: \.phone)
接下来,要查找重复项:
let duplicates = crossReference
.filter { $1.count > 1 }
显然,您应该使用适合您的模型类型,但上面使用了以下Contact
类型:
struct Contact {
let name: String
let phone: String
}
有很多种方法可以实现这一点,因此我不会关注上面的实现细节,而是专注于概念:通过某个键(例如电话号码)构建交叉参考原始数组,然后将结果过滤为仅具有重复值的那些键。
听起来你想要将反映重复项的这个结构展开成一个联系人的单个数组(我不确定为什么要这样做,因为你失去了识别哪些是彼此重复的结构),但如果你想要这样做,你可以用flatMap
来实现:
let flattenedDuplicates = crossReference
.filter { $1.count > 1 } // filter down to only those with multiple contacts
.flatMap { $0.1 } // flatten it down to just array of contacts that are duplicates of something else
cellForRowAtIndexPath
内部添加行。)仔细检查原始数组(例如查看总计数),确保输入正确。 - Rob感觉很聪明。给定一个Int
数组。
let x = [1, 1, 2, 3, 4, 5, 5]
let duplicates = Array(Set(x.filter({ (i: Int) in x.filter({ $0 == i }).count > 1})))
// [1, 5]
请注意,这对于所有涉及方,包括编译器和您本人都极其低效。
我只是在炫耀而已。
编辑:哈哈,有人给这个点了踩,所以我要再强调一遍:请务必不要在生产环境或其他任何地方使用此方法。
i
代替(i: Int)
让编译器处理类型。 - sudovar numbers = [1,2,3,4,5,6,6,6,7,8,8]
let dups = Dictionary(grouping: numbers, by: {$0}).filter { $1.count > 1 }.keys
//Results: [6, 8]
func duplicateIds() -> Dictionary.Keys {
Dictionary(grouping: self, by: { $0.id })
.filter { $1.count > 1 }
.keys
}
- H K整个代码的灵感来自Rob的非常棒的答案。我将它转换成了一个Array
扩展,并为中间步骤赋予了名称以提高可读性:
extension Array where Element: Hashable {
func duplicates() -> Array {
let groups = Dictionary(grouping: self, by: {$0})
let duplicateGroups = groups.filter {$1.count > 1}
let duplicates = Array(duplicateGroups.keys)
return duplicates
}
}
[1, 2, 2, 3, 1].duplicates() -> [1, 2]
var phoneNumbers = [123456, 234567, 345678, 123456, 456789, 135790, 456789, 142638]
func findDuplicates(sortedArray array: [Int]) -> [Int]
{
var duplicates: [Int] = []
var prevItem: Int = 0
var addedItem: Int = 0
for item in array
{
if(prevItem == item && addedItem != item)
{
duplicates.append(item)
addedItem = item
}
prevItem = item
}
return duplicates
}
func sortPhoneNumbers(phoneNumbers: [Int]) -> [Int]
{
return phoneNumbers.sorted({ return $0<$1 })
}
sortPhoneNumbers(phoneNumbers)
findDuplicates(sortPhoneNumbers(phoneNumbers))
func findDuplicates(array: [Int]) -> [Int]
{
var duplicates = Set<Int>()
var prevItem = 0
for item in array
{
if(prevItem == item)
{
duplicates.insert(item)
}
prevItem = item
}
return Array(duplicates)
}
等等。
prevItem
重置为 0
。findDuplicates(sortedArray array: [Int]) -> [Int]
,那么这将是有意义的。但是,读取当前名称的开发人员将无法意识到您传递的数组必须是已排序的。 - Mazyod如果想要根据属性来筛选数组,您可以使用以下方法:
extension Array {
func filterDuplicates(@noescape includeElement: (lhs:Element, rhs:Element) -> Bool) -> [Element]{
var results = [Element]()
forEach { (element) in
let existingElements = results.filter {
return includeElement(lhs: element, rhs: $0)
}
if existingElements.count == 0 {
results.append(element)
}
}
return results
}
}
let filteredContacts = myContacts.filterDuplicates { $0.name == $1.name && $0.phone == $1.phone }
let testNumbers = [1,1,2,3,4,5,2]
let nondupicate = testNumbers.reduce(into: [Int]()) {
if !$0.contains($1) {
$0.append($1)
} else {
print("Found duplicate: \($1)")
}
}
let inputArray = [9820213496, 9546533545, 9820213496, 995543567]
var outputArray = [Int]()
for element in inputArray{
if outputArray.contains(element){
print("\(element) is Duplicate")
}else{
outputArray.append(element)
}
}
print(outputArray) // print Array without duplication
Antoine's solution 在 Swift 3+ 语法中
extension Array {
func filterDuplicates(includeElement: @escaping (_ lhs: Element, _ rhs: Element) -> Bool) -> [Element] {
var results = [Element]()
forEach { (element) in
let existingElements = results.filter {
return includeElement(element, $0)
}
if existingElements.count == 0 {
results.append(element)
}
}
return results
}
}
简单解决方案:
let numbers = ["1","2","3","6","8","3","6","3","5","8","9","7"]
func findDuplicate(list: [String]) -> [String] {
var duplicates = Set<String>()
for element in list {
if list.firstIndex(of: element) != list.lastIndex(of: element) {
duplicates.insert(element)
}
}
return duplicates.sorted()
}