【问题标题】:Split an array then sort the parts by date拆分数组,然后按日期对部分进行排序
【发布时间】:2020-04-28 15:18:26
【问题描述】:

考虑到这个对象数组:

struct Product {
    var isFresh: Bool
    var date: String
}

let products = [Product(isFresh: true, date: "2012-11-05T15:56+0000"),
                Product(isFresh: false, date: "2017-11-05T15:56+0000"),
                Product(isFresh: true, date: "2019-11-05T15:56+0000"),
                Product(isFresh: false, date: "2014-11-05T15:56+0000"),
                Product(isFresh: true, date: "2013-11-05T15:56+0000"),
]

如何编写一个函数,将数组分成两部分(isFresh 和!isFresh),然后按日期对这两部分进行排序,并将标记为 isFresh = true 的产品放在列表顶部。

我负责第一部分:

private func handleProducts(_ products: [Product]) -> [Product] {

    return Dictionary(grouping: products) { $0.isFresh }
        .sorted(by: { $0.key < $1.key })
        .flatMap { $0.value }
}

【问题讨论】:

  • 您应该将您的日期存储为Date,这样就变得微不足道了

标签: arrays swift sorting


【解决方案1】:

使用filtersorted(by:) 两次得到一个包含2 个数组的数组,然后使用flatMap 合并它们

let fresh = [products.filter { $0.isFresh }.sorted(by: { $0.date < $1.date}), 
             products.filter { !$0.isFresh }.sorted(by: { $0.date < $1.date})]
            .flatMap {$0}

【讨论】:

    【解决方案2】:

    如果在将您的产品分组到字典后,您想对每个产品的单个数组进行排序,您可以使用mapValues,例如:

    let results = Dictionary(grouping: products) { $0.isFresh }
        .mapValues { $0.sorted { $0.date < $1.date } }           // sort the subarrays of products within freshness categories
        .sorted { $0.key && !$1.key }                            // sort by freshness
        .flatMap { $0.value }                                    // flatten the subarrays of products
    

    (注意,您使用的是$0.key &lt; $1.key,但布尔值没有固有的排序顺序,这就是我使用$0.key &amp;&amp; !$1.key 模式的原因。)

    但是,如果您真的只是想要一组扁平的产品,先按新鲜度排序,然后按日期排序,我会这样做:

    let results = products.sorted {
        if $0.isFresh != $1.isFresh { return $0.isFresh }
        return $0.date < $1.date
    }
    

    不相关,虽然您的日期字符串是可排序的,因为它们的字母排序恰好与它们的时间排序一致,但我们通常会使用 Date 对象来消除任何歧义,而不是使排序取决于日期。

    所以我建议将date 属性设为Date 类型,并在填充此Product 对象数组时使用日期格式化程序将这些字符串转换为Date 对象。

    【讨论】:

      【解决方案3】:

      首先,按日期对产品数组进行排序

      products.sort {
          $0.date > $1.date
      }
      

      然后,根据需要应用过滤器:-

      let freshProductArr = products.filter {
          return $0.isFresh == true
      }
      
      let staleProductArr = products.filter {
          return $0.isFresh == false
      }
      

      如果你想保持相同的数组:-

      products.sort {
         ($0.date > $1.date)
      }
      
      products.sort {
           $0.isFresh && !$1.isFresh
      }
      

      【讨论】:

      • 我想保留同一个数组
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-28
      • 2019-01-16
      • 1970-01-01
      • 2012-10-04
      • 1970-01-01
      • 2018-04-15
      • 1970-01-01
      相关资源
      最近更新 更多