【问题标题】:Filter array, according to the filter of another array过滤器数组,根据另一个数组的过滤器
【发布时间】:2022-08-11 23:13:33
【问题描述】:

有两个数组 - 第一个是关于日期的,第二个显示当天的支出:

var arrayOfDates = [01.07, 01.07, 03.07, 04.07, 05.07, 05.07, 05.07]
var arrayofCosts = [3, 8, 2, 2, 8, 6, 9]

我想过滤 arrayOfDates 的独特元素。在第二个数组中显示每天的最高价值支出。 所以结果应该是:

var arrayOfDatesModifed = [01.07, 3.07, 04.07, 05.07]
var arrayofNumbersModifed = [8, 2, 2, 9]

所以这个想法包括三个阶段:

  1. 过滤 arrayOfDates 以获取唯一元素
  2. 对于每个唯一的日期,在arrayofCosts 中查找相应的项目
  3. arrayofCosts 中查找每个日期的最大值

    尽管这些任务中的每一项都可能很简单,但我无法弄清楚如何完全完成它们。您的帮助将不胜感激

  • 首先,您不应该有 2 个数组,而应该只有一个。使用自定义 struct,或在最小值时使用元组/字典:如 struct MyStruct { let cost: Int, let Date: Date }。对于您的问题,您可以zip() 链接它们,然后删除“重复项”,保持最高值。
  • 拉尔姆,谢谢你的帮助!我在这里写了整个任务的简化版本。对于项目的其他目的,imo,使用数组更容易。对于这个特定的任务,我可以将它们合并到字典中。但是,如果可以有针对数组的解决方案,那就太好了。
  • 一组自定义结构(或字典)将是更好的方法。而你正是在这种情况下:你有“链接”具有相同索引的值,但如果你删除/修改/更改其中一个位置,你需要对另一个数组应用相同的计算相同的索引。因此,排序、过滤变得更加困难。这是可行的,但有很多额外的工作。现在,如果您有超过 2 个数组(即每个属性一个数组,您将看到噩梦)。
  • 知道了谢谢!我会尝试构建字典或结构。
  • 使用结构数组。这是迄今为止最干净的解决方案。如果您必须使用另一个数组的内容过滤一个数组,请像 Sh_Khan\'s answer 中那样使用 zip 。

标签: ios arrays swift xcode filter


【解决方案1】:

我同意那些有cmets的人。使用单个阵列将是一个真正的痛苦。

让我们实现一个结构来保存我们的数据。

struct Entry: CustomStringConvertible {
    let date: Double
    let cost: Int

    var description: String {
        "(\(date), \(cost))"
    }
}

这些只是您示例中的条目:

let entries: [Entry] = [
    .init(date: 01.07, cost: 3),
    .init(date: 01.07, cost: 8),
    .init(date: 03.07, cost: 2),
    .init(date: 04.07, cost: 2),
    .init(date: 05.07, cost: 8),
    .init(date: 05.07, cost: 6),
    .init(date: 05.07, cost: 9),
]

我要做的第一件事是按日期对所有条目进行分组:

let groupedEntries = Dictionary(grouping: entries) { $0.date }
print(groupedEntries)

这给了我们一个无序的字典,其中键是日期,值是具有相同日期的条目数组:

[1.07: [(1.07, 3), (1.07, 8)], 5.07: [(5.07, 8), (5.07, 6), (5.07, 9)], 3.07: [(3.07, 2)], 4.07: [(4.07, 2)]]

接下来我要做的是提取每个组中成本最高的条目,并丢弃成本较低的条目。我们不需要那些。所以现在我们有一个条目数组,其中低成本元素已被过滤掉。

let uniqueDateMaxEntry = groupedEntries.compactMap { _, entries in
    return entries.max(by: { $0.cost < $1.cost })
}
print(uniqueDateMaxEntry)

这给了我们:

[(1.07, 8), (4.07, 2), (5.07, 9), (3.07, 2)]

如您所见,数组未按日期排序。所以我们现在可以这样做

let sortedUniqueDateMaxEntry = uniqueDateMaxEntry
    .sorted { $0.date < $1.date }
print(sortedUniqueDateMaxEntry)

最后,这给了我们:

[(1.07, 8), (3.07, 2), (4.07, 2), (5.07, 9)]

【讨论】:

    【解决方案2】:
    var arrayOfDates = [01.07, 01.07, 03.07, 04.07, 05.07, 05.07, 05.07]
    var arrayofCosts = [3, 8, 2, 2, 8, 6, 9]
    
    var item = 0.0
    var arrayOfDatesModified = [Double]()
    var arrayOfCostsModified = [Int]()
    var maxCosts = 0
    var indexFor = 0
    
    //Enumerated function helps to get the element with corresponding index
    for (index, element) in arrayOfDates.enumerated() {
        let cost = arrayofCosts[index]
        ///If item is not same as before then its the new item - 01.07(new), 01.07(old), 03.07(new)
        if item != element {
            item = element
            maxCosts = cost
            arrayOfDatesModified.append(item)
            arrayOfCostsModified.insert(maxCosts, at: arrayOfDatesModified.count - 1)
        } else {
            ///If same element cost is higher then replacing with the higher cost
            if maxCosts < cost {
                maxCosts = cost
                arrayOfCostsModified.remove(at: arrayOfDatesModified.count - 1)
                arrayOfCostsModified.insert(maxCosts, at: arrayOfDatesModified.count - 1)
            }
        }
    }
    
    print(arrayOfDatesModified)
    print(arrayOfCostsModified)
    

    上述简单的 for 循环也是解决方案,但没有优化。
    swift语言在最新版本中有很多先进的概念,我们应该避免上述复杂的方法来解决问题。

    1. 不必要的变量声明
    2. 更多的时间和空间复杂性
    3. 缺少概念映射过滤器和结构、分组等,

      它只是一个例子:不应该解决当前的问题,也应该考虑未来的前景。
      它不是您 Sergey_VC 的解决方案,只是想帮助尝试在线快速修复的人。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-30
      • 2014-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-17
      相关资源
      最近更新 更多