使用集合,保持顺序,从一个数组中删除存在于另一个数组中的对象

6
Array1 = [1, 2, 3, 4, 5, 6]

Array2 = [1,5]

我想获得:

Array1 = [2, 3, 4, 6]

我希望使用 Set 来实现此操作,因为这些数组可能会变得更大。同时,保持数组的顺序非常重要。

https://dev59.com/xl0b5IYBdhLWcg3wGN0s#42679608 - muescha
我无法确切理解如何将那个答案应用到我的数组中,您能演示一下吗? - user6520705
请参见下面的答案。 - muescha
1
将以下与编程有关的内容从英语翻译成中文。仅返回已翻译的文本:注意:使用小写变量名称以避免与类名混淆 - muescha
5个回答

22

创建一个包含第二个数组中所有元素的集合,然后过滤第一个数组,获取那些不在该集合中的元素:

let array1 = [5, 4, 1, 2, 3, 4, 1, 2]
let array2 = [1, 5]

let set2 = Set(array2)
let result = array1.filter { !set2.contains($0) }

print(result) // [4, 2, 3, 4, 2]

这将保留第一个数组中的顺序(以及重复元素)。如果第二个数组很大,则使用集合是有优势的,因为查找速度更快。


出色的工作适合我。 - M Hamayun zeb

3
var array1 = [1, 2, 3, 4, 5, 6]

var array2 = [1,5]

var arrayResult = array1.enumerated()
    .filter { !array2.contains($0.0 + 1) }
    .map { $0.1 }

print(arrayResult)

[2, 3, 4, 6]


另一种实现相同结果的方法:

1. 使用过滤器

let arrayResult = array1.filter { element in
    return !array2.contains(element)
}

2. 使用排序

array2.sorted(by: >).forEach { if $0 < self.array1.count { self.array1.remove(at: $0) } }  



使用索引数组删除元素:

  1. Array of Strings and indexes

    let animals = ["cats", "dogs", "chimps", "moose", "squarrel", "cow"]
    let indexAnimals = [0, 3, 4]
    let arrayRemainingAnimals = animals
        .enumerated()
        .filter { !indexAnimals.contains($0.offset) }
        .map { $0.element }
    
    print(arrayRemainingAnimals)
    
    //result - ["dogs", "chimps", "cow"]
    
  2. Array of Integers and indexes

    var numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
    let indexesToRemove = [3, 5, 8, 12]
    
    numbers = numbers
        .enumerated()
        .filter { !indexesToRemove.contains($0.offset) }
        .map { $0.element }
    
    print(numbers)
    
    //result - [0, 1, 2, 4, 6, 7, 9, 10, 11]
    



使用另一个数组中的元素值删除元素

  1. Arrays of integers

    let arrayResult = numbers.filter { element in
        return !indexesToRemove.contains(element)
    }
    print(arrayResult)
    
    //result - [0, 1, 2, 4, 6, 7, 9, 10, 11]
    
  2. Arrays of strings

    let arrayLetters = ["a", "b", "c", "d", "e", "f", "g", "h", "i"]
    let arrayRemoveLetters = ["a", "e", "g", "h"]
    let arrayRemainingLetters = arrayLetters.filter {
        !arrayRemoveLetters.contains($0)
    }
    
    print(arrayRemainingLetters)
    
    //result - ["b", "c", "d", "f", "i"]
    

1
这个方法可以运行,但我认为使用字典会更加简洁。你同意我的看法吗?@Krunal - Sethmr
是的,我同意你的观点。 - Krunal
1
请使用小写的变量名来区分类名。 - muescha

1
使用过滤器函数。
let result = Array1.filter { element in
    return !Array2.contains(element)
}

0

(注意:因为您在问题中添加了and maintaining order,所以我的答案不再正确,因为Set不能保留顺序。那么filter的答案更适合)

使用从Set中减去:

array1 = Array(Set(array1).subtracting(Set(array2)))

你可以将这个作为一个运算符添加:

Using the Array → Set → Array method mentioned by Antonio, and with the convenience of an operator, as freytag pointed out, I've been very satisfied using this:

// Swift 3.x

func - <Element: Hashable>(lhs: [Element], rhs: [Element]) -> [Element]
{
    return Array(Set<Element>(lhs).subtracting(Set<Element>(rhs)))
}

引用自:https://dev59.com/xl0b5IYBdhLWcg3wGN0s#42679608


你能展示一下如何同时使用运算符和减法吗?我还有点困惑。 - user6520705
2
集合是无序的集合。这并不能保证维护原始项目的顺序。 - vacawama
谢谢,是的我知道 - 但他后来改变了原来的问题并添加了“维护顺序”。我在我的答案中添加了一条注释。 - muescha

0
let array1 = [1, 2, 3, 4, 5, 6]
let array2 = [1,5]

let array3 = array1.reduce([]) { array2.contains($1) ? $0 : $0 + [$1] } 

print(array3)  // "[2, 3, 4, 6]\n"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接