Arrays 如何根据另一个数组从数组中删除数据?

Arrays 如何根据另一个数组从数组中删除数据?,arrays,swift,Arrays,Swift,我想根据索引删除对FALSE的值 操作后输出应如下所示: let guideArray = ["TRUE", "TRUE", "TRUE", "FALSE", "TRUE", "TRUE", "FALSE"] let toBeRemoved = ["ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN"] 我尝试使用for-in-loop,如下所示,但它失败了,因为它每次都运行数组计数更改 toBeRemoved = ["ONE", "TWO"

我想根据索引删除对FALSE的值

操作后输出应如下所示:

let guideArray = ["TRUE", "TRUE", "TRUE", "FALSE", "TRUE", "TRUE", "FALSE"]
let toBeRemoved = ["ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN"]
我尝试使用for-in-loop,如下所示,但它失败了,因为它每次都运行数组计数更改

toBeRemoved = ["ONE", "TWO", "THREE", "FIVE", "SIX"]
//Forth and seventh element deleted

您可以从最后一个索引开始并计数到第一个索引,而不是从第一个索引开始并计数到最后一个索引。如果从数组中删除某个元素,它只会在其后移动内容,因此通过倒计时,可以确保仍然需要影响的元素没有通过删除以前的元素而移动

在您的示例中,您尝试从索引0开始,然后计数到索引6。这意味着,当您到达数组中的第四个元素并将其删除时,需要迭代的其余元素将向前移动一个空间,这将导致您的问题

在您的例子中,此代码将从索引6(最后一个索引)开始,并查看是否应该删除该索引。它应该被删除,因此您将删除它。然后您将转到索引5,它仍然是“六”,因为从末尾删除“七”并不会改变前面元素的顺序

for i in 0...(guideArray.count-1) {
  if guideArray[i] == "FALSE"{
    toBeRemoved.removeAtIndex(i) 
    //this failed because of every time it runs toBeRemoved.count integer changes
  }
}

您可以从最后一个索引开始并计数到第一个索引,而不是从第一个索引开始并计数到最后一个索引。如果从数组中删除某个元素,它只会在其后移动内容,因此通过倒计时,可以确保仍然需要影响的元素没有通过删除以前的元素而移动

在您的示例中,您尝试从索引0开始,然后计数到索引6。这意味着,当您到达数组中的第四个元素并将其删除时,需要迭代的其余元素将向前移动一个空间,这将导致您的问题

在您的例子中,此代码将从索引6(最后一个索引)开始,并查看是否应该删除该索引。它应该被删除,因此您将删除它。然后您将转到索引5,它仍然是“六”,因为从末尾删除“七”并不会改变前面元素的顺序

for i in 0...(guideArray.count-1) {
  if guideArray[i] == "FALSE"{
    toBeRemoved.removeAtIndex(i) 
    //this failed because of every time it runs toBeRemoved.count integer changes
  }
}
解决方案 这是一个函数编程非常有用的问题

给定这两个数组

for i in (guideArray.count - 1).stride(through: 0, by: -1) {
    if guideArray[i] == "FALSE"{
        toBeRemoved.removeAtIndex(i)
    }
}
您可以通过这种方式执行筛选

let words = ["ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN"]
let shouldRemove = ["TRUE", "TRUE", "TRUE", "FALSE", "TRUE", "TRUE", "FALSE"]
它是如何工作的? 这将创建一个序列,其中第一个数组的第n个元素与第二个数组的第n个元素配对。因此,这个序列的每个元素都有两个组成部分(一个来自
单词
,另一个来自
shoulldremove

下一步

zip(words, shouldRemove)
---------| ---------
ONE      | TRUE
---------| ---------
TWO      | TRUE
---------| ---------
THREE    | TRUE
---------| ---------
FOUR     | FALSE
---------| ---------
FIVE     | TRUE
---------| ---------
SIX      | TRUE
---------| ---------
SEVEN    | FALSE
---------| ---------
---------| ---------
ONE      | TRUE
---------| ---------
TWO      | TRUE
---------| ---------
THREE    | TRUE
---------| ---------
FIVE     | TRUE
---------| ---------
SIX      | TRUE
---------| ---------
这将过滤序列,只留下第二个组件为字符串“TRUE”的元素

下一步

zip(words, shouldRemove)
---------| ---------
ONE      | TRUE
---------| ---------
TWO      | TRUE
---------| ---------
THREE    | TRUE
---------| ---------
FOUR     | FALSE
---------| ---------
FIVE     | TRUE
---------| ---------
SIX      | TRUE
---------| ---------
SEVEN    | FALSE
---------| ---------
---------| ---------
ONE      | TRUE
---------| ---------
TWO      | TRUE
---------| ---------
THREE    | TRUE
---------| ---------
FIVE     | TRUE
---------| ---------
SIX      | TRUE
---------| ---------
最后,对于每个元素,只返回第一个组件(来自
words
的组件)

为什么我要重命名数组的名称?
  • 在Swift中,我们不在其名称中使用变量的类型。变量的名称应该表示它的值
  • 数组的名称是反向的。您将
    toBeRemoved
    命名为包含内容的数组。它不应该是带有“
    ”真“/”假“
    ”的名称吗
解决方案 这是一个函数编程非常有用的问题

给定这两个数组

for i in (guideArray.count - 1).stride(through: 0, by: -1) {
    if guideArray[i] == "FALSE"{
        toBeRemoved.removeAtIndex(i)
    }
}
您可以通过这种方式执行筛选

let words = ["ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN"]
let shouldRemove = ["TRUE", "TRUE", "TRUE", "FALSE", "TRUE", "TRUE", "FALSE"]
它是如何工作的? 这将创建一个序列,其中第一个数组的第n个元素与第二个数组的第n个元素配对。因此,这个序列的每个元素都有两个组成部分(一个来自
单词
,另一个来自
shoulldremove

下一步

zip(words, shouldRemove)
---------| ---------
ONE      | TRUE
---------| ---------
TWO      | TRUE
---------| ---------
THREE    | TRUE
---------| ---------
FOUR     | FALSE
---------| ---------
FIVE     | TRUE
---------| ---------
SIX      | TRUE
---------| ---------
SEVEN    | FALSE
---------| ---------
---------| ---------
ONE      | TRUE
---------| ---------
TWO      | TRUE
---------| ---------
THREE    | TRUE
---------| ---------
FIVE     | TRUE
---------| ---------
SIX      | TRUE
---------| ---------
这将过滤序列,只留下第二个组件为字符串“TRUE”的元素

下一步

zip(words, shouldRemove)
---------| ---------
ONE      | TRUE
---------| ---------
TWO      | TRUE
---------| ---------
THREE    | TRUE
---------| ---------
FOUR     | FALSE
---------| ---------
FIVE     | TRUE
---------| ---------
SIX      | TRUE
---------| ---------
SEVEN    | FALSE
---------| ---------
---------| ---------
ONE      | TRUE
---------| ---------
TWO      | TRUE
---------| ---------
THREE    | TRUE
---------| ---------
FIVE     | TRUE
---------| ---------
SIX      | TRUE
---------| ---------
最后,对于每个元素,只返回第一个组件(来自
words
的组件)

为什么我要重命名数组的名称?
  • 在Swift中,我们不在其名称中使用变量的类型。变量的名称应该表示它的值
  • 数组的名称是反向的。您将
    toBeRemoved
    命名为包含内容的数组。它不应该是带有“
    ”真“/”假“
    ”的名称吗

另一种解决方案,无需压缩/循环:

---------
ONE      
---------
TWO
---------
THREE
---------
FIVE 
---------
SIX 
---------

在这里,我们通过在“FALSE”位置用nil替换元素,将flatMapping
移动到
数组中

另一种解决方案,没有压缩/循环:

---------
ONE      
---------
TWO
---------
THREE
---------
FIVE 
---------
SIX 
---------

在这里,我们将通过在“FALSE”位置用nil替换元素来删除flatMapping
数组

您可以向后循环数组,而不是向后循环,这是什么意思?您可以向后循环数组,而不是向后循环,这是什么意思?无需
映射
然后
flatMap
,只需做一个
flatMap
;)@哈米什:当然,我做了一件多么有趣的事!我将根据您的建议更改答案无需
map
然后
flatMap
,只需执行一个
flatMap
;)@哈米什:当然,我做了一件多么有趣的事!我会根据你的建议改变答案