【问题标题】:how to filter the array when we have inner array and need to apply filter on inner array当我们有内部数组并且需要在内部数组上应用过滤器时如何过滤数组
【发布时间】:2018-11-09 06:26:48
【问题描述】:

假设我有如下数据。

[
    {
        hotelName : "Hotel 1",
        hotelType : 1
        prices : 
                [
                    {
                        roomType: "Single Room",
                        price : 1231
                    },
                    {
                        roomType: "Twin Room",
                        price : 1232
                    },
                    {
                        roomType: "Triple Room",
                        price : 1233
                    },
                ]
    },
    {
        hotelName : "Hotel 2",
        hotelType : 2
        prices : 
                [
                    {
                        roomType: "Single Room",
                        price : 1241
                    },
                    {
                        roomType: "Twin Room",
                        price : 1242
                    },
                    {
                        roomType: "Triple Room",
                        price : 1243
                    },
                ]
    }
]

我想要的是用价格过滤酒店。

假设我想过滤得到低于范围的酒店。

价格范围为 1231-1233 >> 这将只返回酒店 1。

价格范围为 1231-1431 >> 这将返回酒店 1 和酒店 2。

我有相同类型的过滤器,但我只有 1 个价格,所以我正在做的事情如下。

finalArray = finalArray.filter() {
                    CGFloat(($0.prices![0].price)!) >= minValue 
                    &&
                    CGFloat(($0.prices![0].price)!) <= maxValue
             }

但是现在我有一系列价格,所以我不知道在这种情况下如何处理。

问题出在一行

$0.prices![0].price
          ^^^

有人可以为我指出如何实现此过滤器的正确方向吗?

【问题讨论】:

  • 您想从酒店数组中获取过滤后的项目吗?我的意思是 { roomType: String, price: Int }

标签: swift filter swift4


【解决方案1】:

你可以这样做:

struct Price {
   let roomType: String
   let price: Double
}

struct Hotel {
   let hotelName: String
   let hotelType: Int
   let prices: [Price]
}

let hotel1 = Hotel(hotelName: "Hotel 1", hotelType: 1, prices: [
    Price(roomType: "Single Room", price: 1231),
    Price(roomType: "Twin Room", price: 1232),
    Price(roomType: "Triple Room", price: 1233)
])

let hotel2 = Hotel(hotelName: "Hotel 2", hotelType: 1, prices: [
    Price(roomType: "Single Room", price: 1241),
    Price(roomType: "Twin Room", price: 1242),
    Price(roomType: "Triple Room", price: 1243)
])

func getHotelsInRange(_ hotels: [Hotel],
                      from min: Double,
                      to max: Double) -> [Hotel] {
    return hotels.filter { h in
        h.prices.contains{ p in
            switch p.price {
            case min...max:
                return true
            default:
                return false
            }
        }
    }
}

let result = getHotelsInRange([hotel1, hotel2], from: min, to: max)

【讨论】:

  • 致命错误:无法为 min...max形成具有上界 的范围>
  • 是的,看起来我的参数顺序错误。更清楚的是从最小值到最大值
【解决方案2】:

您只需要检查prices 数组中是否有任何不符合条件的元素。您可以使用带有否定谓词的Array.contains 来实现此目的,这样contains 在您发现错误值时立即返回(即检查低于最小值的值或大于最大值的值)。

finalArray = finalArray.filter() { hotelInfo in
    !hotelInfo.prices!.contains(where: {CGFloat($0) <= minValue}) && !hotelInfo.prices!.contains(where: {CGFloat($0) >= maxValue})
}

【讨论】:

  • 什么是hotelInfo。我知道hotelInfo 将成为酒店的 1 个对象...我的主要问题是我将如何定义?
  • 不需要定义,只是filter的命名参数。它与$0 相同,但由于您将有2 个嵌套闭包,包括containswhere 子句,因此命名其中一个会更清楚。
  • 很高兴我能帮上忙
  • hotelInfo.prices?.contains {!(minValue..&lt;maxValue ~= CGFloat($0))} == false
  • @LeoDabus :我使用了hotelInfo.prices?.contains {minValue...maxValue ~= $0},它工作正常......
猜你喜欢
  • 1970-01-01
  • 2021-05-21
  • 2021-12-25
  • 1970-01-01
  • 1970-01-01
  • 2016-11-03
  • 1970-01-01
  • 2016-09-28
  • 1970-01-01
相关资源
最近更新 更多