xcode表视图控制器搜索多个数组

时间:2018-01-09 08:08:02

标签: swift xcode uitableview

我添加了一个成功搜索菜单名称的搜索栏。但是,菜单价格根本没有过滤,我不知道如何控制这两个数组,当我搜索并获得菜单[“a”,“c”]的结果时,价格数组显示与菜单数组相对应的价格;价格[“价格”,“价格c”]。该列表显示三个对象;菜单图像,菜单名称和价格。

var menu = ["Ice Tea (Large)", "Ice Tea (Small)", "Green Apple Refresher (Large)","Green Apple Refresher (Small)", "Peach Refresher (Large)", "Peach Refresher (Small)"]
var price = ["Rs.80", "Rs.50", "Rs.110", "Rs.80", "Rs.110", "Rs.80"]
var currentMenuNameArray = [String]()
class myMenu: UITableViewController, UISearchBarDelegate
{

@IBOutlet weak var tdMenuSearchBar: UISearchBar!

override func viewDidLoad()
{
    super.viewDidLoad()
    tdMenuSearchBar.delegate = self
    currentMenuNameArray = menu
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return currentMenuNameArray.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as!TigersDenTableViewCell

    cell.tdMenuImage.image = UIImage(named:currentMenuNameArray[indexPath.row] + ".jpg")
    cell.tdMenuName.text = currentMenuNameArray[indexPath.row]
    cell.tdMenuPrice.text = price[indexPath.row]

    return cell
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
    return 100
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String)
{
    guard !searchText.isEmpty else {
        currentMenuNameArray = menu
        tableView.reloadData()
        return
    }
    currentMenuNameArray = menu.filter( { (menu:String) -> Bool in        menu.lowercased().contains(searchText.lowercased())
    })
    tableView.reloadData()
}
}

3 个答案:

答案 0 :(得分:1)

您可以zip(因为您提到the price array displays the prices that are correspondent to the menu array)两个数组,filtermenu值并获得两个过滤数组。

let searchString = "Green"

let menu = ["Ice Tea (Large)", "Ice Tea (Small)", "Green Apple Refresher (Large)","Green Apple Refresher (Small)", "Peach Refresher (Large)", "Peach Refresher (Small)"]
let price = ["Rs.80", "Rs.50", "Rs.110", "Rs.80", "Rs.110", "Rs.80"]

let result = zip(menu, price).filter { menuItem, _ in
    menuItem.lowercased().contains(searchString.lowercased())
}

print(result) // array of tuples [("Green Apple Refresher (Large)", "Rs.110"), ("Green Apple Refresher (Small)", "Rs.80")]

let filteredMenu = result.map({ $0.0 })
let filteredPrice = result.map({ $0.1 })

print(filteredMenu, filteredPrice) // two separate arrays ["Green Apple Refresher (Large)", "Green Apple Refresher (Small)"] ["Rs.110", "Rs.80"]

答案 1 :(得分:1)

var menu = ["Ice Tea (Large)", "Ice Tea (Small)", "Green Apple Refresher (Large)","Green Apple Refresher (Small)", "Peach Refresher (Large)", "Peach Refresher (Small)"]
var price = ["Rs.80", "Rs.50", "Rs.110", "Rs.80", "Rs.110", "Rs.80"]

问题是menuprice是同步的。这意味着如果从menu中删除一个项目,则需要删除price中相应的一个(相同索引)。但是保持手动同步是为了增加工作量,而对它们使用单​​个阵列就足够了,而且更有意义。

快速解决方案:使用字典数组:

var menu:[[String:String]] = ["Name":"Ice Tea (Large)", "Price":"Rs.80",
                              "Name":"Ice Tea (Small)", "Price":"Rs.50",
                              ...]

然后:

cell.tdMenuImage.image = UIImage(named:currentArray[indexPath.row]["Name"] + ".jpg")
cell.tdMenuName.text = currentArray[indexPath.row]["Name"]
cell.tdMenuPrice.text = currentArray[indexPath.row]["Price"]

currentMenuNameArray = menu.filter( { (menu:[String:String]) -> Bool in   
    menu["Name"].lowercased().contains(searchText.lowercased())
})

我不知道代码的范围,但我建议创建自己的对象/结构,使用字符串属性name,双属性price,也许来自自定义枚举的属性来定义它是大还是小。

它不是很漂亮的Swift代码,但它更多的是解释逻辑,以及什么可以为您提供使用自定义对象的好处:

import UIKit

enum MenuSize: String {
    case small = "Small"
    case large = "Large"
}

class Menu: NSObject {
    let name: String
    let price: Double
    let size: MenuSize

    required init(withName name: String, withPrice price: Double, andSize size: MenuSize) {
        self.name = name
        self.price = price
        self.size = size
    }

    func displayableName() -> String {
        return name + " (" + self.size.rawValue + ")"
    }

    func imageName() -> String {
        return self.name + ".jpg"
    }
}

要测试的示例代码:

let menu1 = Menu.init(withName: "Ice tea", withPrice: 0.80, andSize: .large)
let menu1Name = menu1.displayableName()
print("menu1Name: \(menu1Name)")

let menu2 = Menu.init(withName: "Ice tea", withPrice: 0.50, andSize: .small)
let menu3 = Menu.init(withName: "Diet Coke", withPrice: 0.50, andSize: .small)
let menu4 = Menu.init(withName: "Diet Coke", withPrice: 1.00, andSize: .large)

let array = [menu1, menu2, menu3, menu4]

let filtered = array.filter { (menuToTest:Menu) -> Bool in
    return menuToTest.name.lowercased().contains("et".lowercased())
}

您可以使用NumberFormatter以卢比显示价格。 (Related SO question)。

tableView(_ tableView:cellForRowAt:)中的代码是:

let currentMenu = currentArray[indexPath.row]
cell.tdMenuImage.image = UIImage(named: currentMenu.imageName())
cell.tdMenuName.text = currentMenu.displayableName()
cell.tdMenuPrice.text = //Use the formatter

答案 2 :(得分:0)

添加@ pacification的答案,还要过滤价格数组..尝试按照

let searchString = "5"

let menu = ["Ice Tea (Large)", "Ice Tea (Small)", "Green Apple Refresher (Large)","Green Apple Refresher (Small)", "Peach Refresher (Large)", "Peach Refresher (Small)"]
let price = ["Rs.80", "Rs.50", "Rs.110", "Rs.80", "Rs.110", "Rs.80"]

    let result = zip(menu, price).filter { menuItem, priceItem in
        menuItem.lowercased().contains(searchString.lowercased()) ||
        priceItem.lowercased().replacingOccurrences(of: "rs.", with: "").contains(searchString.lowercased())
    }


print(result) // array of tuple [("Ice Tea (Small)", "Rs.50")]

let filteredMenu = result.map({ $0.0 }) let filteredPrice = result.map({ $0.1 })

print(filteredMenu, filteredPrice) // two separate array ["Ice Tea (Small)"] ["Rs.50"]