我添加了一个成功搜索菜单名称的搜索栏。但是,菜单价格根本没有过滤,我不知道如何控制这两个数组,当我搜索并获得菜单[“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()
}
}
答案 0 :(得分:1)
您可以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"]
答案 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"]
问题是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
以卢比显示价格。 (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"]