2016-12-13 236 views
0

從我前面回答的問題繼:Hiow獲得較低和較高的結果.filter枚舉值.MAP,(_:最大)應用

Why does map(_:) in Swift Playground return a String and not a tuple?

鑑於orders陣列,一個球員有銷售

let orders = [2,3,5] 
let goods = 1 

注意一些goods:數組不應該被訂購。

我想要應用一些相等規則並返回三個規則的索引和值元組;

(一)完美匹配

解決前面的問題

(b)如果數量較少規則有效

貨物的數量不等於任何訂單;
此外,他的商品數量少於最高訂單價值。

後效果:僅返回最高順序值& &索引

在這個例子中,答案是

[2, 3, 5]因爲產品= 1的陣列,並且是比任何訂單的下

同樣if goods = 4那麼答案將是:[5]

當這個規則是真的;只返回最高的訂單價值。

目前我通過這樣做:

let lower = orders.filter({goods < $0}) 
print ("Lower: \(lower)") 
// Output is Lower: [2, 3, 5] 

或把它更準確,我用:

let lower = orders.filter({goods < $0}).max() ?? 0 as Int 
// Output is 5 

然而,這不會讓我知道這個規則爲真的orders數組的索引。

(c)如果人數較多規則有效

球員有更多的商品比最高的訂單價值 訂單陣列中流露出

後的效果:僅返回最高的訂單價值& &索引

實施例:

If goods = 8

let higher = orders.filter({goods > $0 }).max() ?? 0 as Int 
print ("Higher: \(higher)") 
// Output is: 5 

然而;這不會讓我知道這個規則爲真的orders數組的索引。

問題>

如何通過上述過濾器(),其中的.max()被應用到給定的最低和更高數量的規則返回數組索引&數組值枚舉?

非常感謝


編輯:更新

現在我已經編入if語句;

// should only return the first result; regardless of how many results returned 
let perfectMatch = orders.enumerated().filter({goods == $0.element}).flatMap({ 
    [($0.offset, $0.element)] 
}).first 

if let perfectMatch = perfectMatch { 
    print ("Perfect Match: \(perfectMatch)") 
} 
else { 

    let lower = orders.enumerated().max(by: {goods < $1.element}).flatMap({ 
     [($0.offset, $0.element)] 
    }) 

    if let lower = lower { 
     print("Lower \(lower)") 
    } 
    else { 

     let higher = orders.enumerated().max(by: {goods > $1.element}).flatMap({[($0.offset, $0.element)]}) 

     print("higher \(higher!)") 

// if higher fails (unlikely), return a nil 

    } 

} 

的問題是,如果商品是比任何高/所有的數字,即:8和訂單[1,1,1]然後下邊界應該失敗/告吹,但它總是返回

Lower [(0, 1)]

回答

2

您是否嘗試過在orders上使用enumerated()實例方法?

這將返回一個EnumeratedSequence,本質上提供一個索引值和元素值。

let orders = [2,3,5] 

// goods == 8 
let higher = orders.enumerated().max(by: {goods > $1.element}).flatMap({[($0.offset, $0.element)]}) 
print(higher!) // Prints [(2, 5)] 

// goods == 1 
let lower = orders.enumerated().filter({goods < $0.element}) 
print(lower) // Prints [(0, 2), (1, 3), (2, 5)] 

// goods == 4 
let lower = orders.enumerated().filter({goods < $0.element}) 
print(lower) // Prints [(2, 5)] 

編輯:

根據您的意見所做的更改。

封裝Int數組和您的規則檢查的訂單類型。

struct Order { 
    private var _orders: [Int] 
    var orders: [Int] { 
     return _orders 
    } 

    init(orders: [Int]) { 
     _orders = orders 
    } 

    func match(_ good: Int) -> (Int, Int)? { 
     var match = _orders.enumerated().filter { 
      good == $0.element 
     } 

     match = match.flatMap { 
      [($0.offset, $0.element)] 
     } 
     return match.first 
    } 

    func lower(_ good: Int) -> (Int, Int)? { 
     let lower = _orders.enumerated().max { 
      a, b in 
      return a.element > b.element 
     } 

     let upper = _orders.enumerated().max { 
      a, b in 
      return a.element < b.element 
     } 

     guard let lowerValue = lower?.1, let upperValue = upper?.1 else { 
      return nil 
     } 

     let range = Range(uncheckedBounds: (lowerValue, upperValue)) 
     let inRange = range.contains(good) 

     if inRange || good < range.lowerBound { 
      return upper 
     } else { 
      return nil 
     } 
    } 

    func higher(_ good: Int) -> (Int, Int)? { 
     let upper = _orders.enumerated().max { 
      a, b in 
      return a.element < b.element 
     } 

     guard let upperValue = upper?.element else { 
      return nil 
     } 

     if good > upperValue { 
      return upper 
     } else { 
      return nil 
     } 
    } 
} 

用法:

var order = Order(orders: [2, 3, 5]) 
let good = 8 

if let match = order.match(good) { 
    print("Found match for: \(good) in \(order.orders) at index: \(match.0)") 
} else { 
    print("No Match.. Checking Lower...") 
    if let lower = order.lower(good) { 
     print("Found lower for: \(good) in \(order.orders) at index: \(lower.0)") 
    } else { 
     print("No Lower.. Checking Higher...") 
     if let higher = order.higher(good) { 
      print("Found higher for: \(good) in \(order.orders) at index: \(higher.0)") 
     } else { 
      print("Failure.") 
     } 
    } 
} 

輸出:

No Match.. Checking Lower... 
No Lower.. Checking Higher... 
Found higher for: 8 in [2, 3, 5] at index: 2 
+0

您好,我會給這個去!非常感謝 – zardon

+0

這似乎工作,但較低的一個返回多個結果;當它應該返回返回結果的max()。在這方面,我複製並倒置了你發佈的更高的過濾器算法,並且似乎工作;目前我正在測試各種結果。 – zardon

+0

你好。當商品是8時,下邊界檢查應該返回零,但總是返回Lower [(0,1)],這是不正確的;換句話說 - 如果下邊界檢查無法爲其相等比較找到任何匹配,則下邊界檢查將失敗 – zardon