【问题标题】:I'm trying to undo a filter result if I click on the same button again如果我再次单击同一个按钮,我正在尝试撤消过滤结果
【发布时间】:2017-02-09 00:48:45
【问题描述】:

如果我再次单击同一个按钮,我正在尝试撤消过滤结果。我的目标是过滤一个数组并检查一个单词是否有多个字符,以及其他一些过滤器。问题是,一旦我过滤了该数组,有没有办法返回并将过滤数组恢复到以前的情况?

这是我当前的代码

Class FilterClas {

 var filteredArray = [InfoObject]()
 var isChecked = false 

@IBAction func filterArray(_ sender: Any) {
     if !isChecked {
        isChecked = true


        filteredArray = filteredArray.filter({ m in m.firstImg.characters.count < 160})
        print(filteredArray)
         }
      } else {
        isChecked = false
 // What do I do here to revert the changes I made to the array. 
      }
     }
   }

如果有人需要更多说明,请告诉我。

【问题讨论】:

  • 您需要单独存储原始数组。
  • 如果我只想使用一个过滤器,那将是一个很好的解决方案,而且绝对是最简单的解决方案,但随着我不断使用不同的过滤器并在它们之上添加,我将无法做到这一点。它会成功,所以我每次都必须从乞讨开始,而且我将无法访问我之前所做的过滤器。
  • 为什么会有问题?每当其中一个过滤器发生变化时,重新应用它们。如果您有如此庞大的列表或如此复杂的过滤器会导致性能问题,那么您需要解决导致该问题的设计选择。但是没有“将 var 恢复为以前的值”的概念,除非您有另一个支持变量。

标签: ios arrays swift filter


【解决方案1】:

只是为了使其他一些答案和 cmets 具体化,您可以跟踪您的过滤器并根据需要应用它们。例如:

class Filter {
    var array: [Int] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    var filters: [(Int) -> Bool] = []

    var filteredArray: [Int] {
        var filteredArray = array
        for filter in filters {
            filteredArray = filteredArray.filter(filter)
        }
        return filteredArray
    }
}

let f = Filter()
f.filteredArray
f.filters.append { $0 < 8 }
f.filteredArray
f.filters.append { $0 % 2 == 0 }
f.filteredArray
f.filters.append { $0 > 2 }
f.filteredArray

或者,如果您希望能够打开和关闭单个过滤器,您可以这样做:

struct Filter {
    let filter: (Int) -> Bool
    var enabled: Bool
}

class Filtered {
    var array: [Int] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    var filters: [Filter] = [
        Filter(filter: { $0 < 8 }, enabled: true),
        Filter(filter: { $0 % 2 == 0 }, enabled: false),
        Filter(filter: { $0 > 2 }, enabled: true),
    ]

    var filteredArray: [Int] {
        var filteredArray = array
        for filter in filters {
            if filter.enabled {
                filteredArray = filteredArray.filter(filter.filter)
            }
        }
        return filteredArray
    }
}

let f = Filtered()
f.filteredArray
f.filters[1].enabled = true
f.filteredArray

【讨论】:

  • 感谢您的详尽回答。它真的帮助了我。我一直在玩这个 put 无法弄清楚一件事。我想将该结构更改为字典而不是数组。我尝试了不同的变化,但似乎无法使其工作。有什么建议吗?
  • 我不明白您所说的“将结构更改为字典而不是数组”是什么意思。你遇到了什么问题?
  • 所以现在我不得不引用像 f.filter[1].enabled 这样的过滤器。我希望能够通过字典访问并执行 f.filter[filter1].enabled = true 之类的操作。当我进入 45 范围内的更多过滤器时,我觉得字典会是访问过滤器的更好方法。我问的更有意义吗?
  • 当然;那没问题。你只想要var filters: [String: Filter] 吗?这看起来很简单。
  • 谢谢。是的,我试图更改过滤器结构并遇到问题。是的,这更有意义。
【解决方案2】:

您无法将数组恢复为之前的形式。

在代码中,您将使用新数组覆盖 filtered 数组的值。请记住,filter 返回一个新数组,它不会修改现有数组。因此,未过滤的数组已经被销毁了。

您可以做的是将过滤后的数组存储为未过滤的数组。这样,当未选中过滤器时,您将使用未过滤的过滤器。

这可以在以下代码中看到:

Class FilterClass {

    //unfilteredArray would never be modified
    var unfilteredArray = [InfoObject]()
    //currentArray is the one you are currently using, filtered or not
    var currentArray = [InfoObject]()
    var isChecked = false 

    @IBAction func filterArray(_ sender: Any) {
        if !isChecked {
            isChecked = true
            currentArray = unfilteredArray.filter({ m in m.firstImg.characters.count < 160})
        } else {
            isChecked = false
            currentArray = unfilteredArray
        }
    }
}

【讨论】:

  • 这不是我真正想要的答案,但你让我更好地理解了过滤数组正在被破坏。问题是我有 30 个按钮,您可以在其中进一步过滤列表。如果我这样做,我会回到原始数组并丢失我所做的所有其他过滤器。也许我需要重新考虑我的架构并弄清楚是否有更好的方法来做到这一点。
猜你喜欢
  • 2022-10-18
  • 1970-01-01
  • 2023-04-11
  • 2018-04-25
  • 2021-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-14
相关资源
最近更新 更多