我添加了一个搜索栏,可以成功搜索菜单名称。但是,菜单价格根本不过滤,我不知道如何控制两个数组,当我搜索并得到菜单["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"]
问题是menu
和price
是同步的。这意味着如果从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"]