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



我添加了一个搜索栏,可以成功搜索菜单名称。但是,菜单价格根本不过滤,我不知道如何控制两个数组,当我搜索并得到菜单["a", "c"]的结果时,价格数组显示与菜单数组相对应的价格;价格["a的价格","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()
}
}

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

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"]
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以卢比显示价格。(相关问题(。

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

添加到@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"]

最新更新