我有一个包含嵌套字典作为值的字典。我要完成的工作是搜索嵌套字典,然后将那些匹配的值添加到名为“ FilterData”的变量中。
var Data: [Int : [String : String]] = [:]
var filteredData: [Int : [String : String]] = [:]
let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %@", searchController.searchBar.text!)
//Don't know how to filter the nested dictionary, I can filter an array.
let array = (Data as NSArray).filtered(using: searchPredicate)
filteredData = array as! [String]
有人知道我该如何处理吗?
答案 0 :(得分:1)
为了给您一些示例,我如何在冠军联赛中从获胜者和亚军中获得一组数据进行过滤。在主词典中,package calculator1;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class MyFirstGUI extends JFrame implements ActionListener {
int val1 = 0;
int val2 = 0;
int sum = 0;
JTextField t1 = new JTextField(10);
JButton b1 = new JButton("+");
JButton b2 = new JButton("*");
JButton b3 = new JButton("/");
JButton b4 = new JButton("=");
int n1, n2;
public MyFirstGUI() {
setLayout(new FlowLayout());
setVisible(true);
setSize(500, 500);
JLabel l1 = new JLabel("Result");
add(l1);
add(t1);
add(b1);
add(b2);
add(b3);
add(b4);
b1.addActionListener(this);
b2.addActionListener(this);
b3.addActionListener(this);
b4.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
int val1, val2, sum = 0;
val1 = Integer.parseInt(t1.getText());
if (e.getSource() == b1) {
t1.setText("");
}
if (e.getSource() == b4) {
val2 = Integer.parseInt(t1.getText());
sum = val1 + val2;
t1.setText("" + sum);
}
}
}
class Test {
public static void main(String[] args) {
MyFirstGUI p = new MyFirstGUI();
}
}
键对应于比赛的年份。里面的字典有两个键:Int
和1stPlace
。例如,在2018年皇家马德里击败利物浦的比赛中,字典将如下所示:
2ndPlace
假设这种结构,2018: ["1stPlace": "Real Madrid", "2ndPlace": "Liverpool"]
变量的结果为2018年至2011年。如果您想知道谁在2018年获胜,可以执行以下操作:
Data
如果您想知道皇马何时获胜,您会像这样:
filteredData = Data.filter { $0.key == 2018 }
如果您想知道皇马何时击败马德里竞技,您可以这样做:
filteredData = Data.filter { $0.value["1stPlace"] == "Real Madrid" }
在filteredData = Data.filter {
$0.value["2ndPlace"] == "Atlético Madrid" &&
$0.value["1stPlace"] == "Real Madrid"
}
中有结果时,可以用不同的方式查询数据:可以按年份排序,可以仅提取年份,等等。
以下代码是我用来测试各种查询的游乐场:
filteredData
游乐场的输出为:
import Foundation
typealias DictOfDicts = [Int : [String : String]]
var Data: DictOfDicts = [
2018:
["1stPlace": "Real Madrid", "2ndPlace": "Liverpool"],
2017:
["1stPlace": "Real Madrid", "2ndPlace": "Juventus"],
2016:
["1stPlace": "Real Madrid", "2ndPlace": "Atlético Madrid"],
2015:
["1stPlace": "Barcelona", "2ndPlace": "Juventus"],
2014:
["1stPlace": "Real Madrid", "2ndPlace": "Atlético Madrid"],
2013:
["1stPlace": "Bayern Munich", "2ndPlace": "Borussia Dortmund"],
2012:
["1stPlace": "Chelsea", "2ndPlace": "Bayern Munich"],
2011:
["1stPlace": "Barcelona", "2ndPlace": "Manchester United"]
]
var filteredData: DictOfDicts = [:]
print("Results from 2017 to present")
print("----------------------------")
filteredData = Data.filter { $0.key >= 2017 } // Filter from 2017 to present
filteredData
.sorted { $0.key > $1.key } // Sort by year
.forEach {
print("In \($0.key) \($0.value["1stPlace"]!) defeated \($0.value["2ndPlace"]!)")
}
print("")
print("Results before 2015")
print("----------------------------")
filteredData = Data.filter { $0.key < 2015 } // Filter before 2015
filteredData
.sorted { $0.key > $1.key } // Sort by year
.forEach {
print("In \($0.key) \($0.value["1stPlace"]!) defeated \($0.value["2ndPlace"]!)")
}
print("")
filteredData = Data.filter { $0.value["1stPlace"] == "Real Madrid" } // Filter Real Madrid won
var years = filteredData
.sorted { $0.key < $1.key } // Sort by year
.map { "\($0.key)" } // Convert year to string
.joined(separator: ", ") // Convert to comma separated single string
print("Real Madrid won in: \(years)")
print("")
filteredData = Data.filter { $0.value["2ndPlace"] == "Juventus" } // Filter Juventus lost
years = filteredData
.sorted { $0.key > $1.key } // Sort by year
.map { "\($0.key)" } // Convert year to string
.joined(separator: ", ") // Convert to comma separated single string
print("Juventus lost the final match in: \(years)")
print("")
filteredData = Data.filter {
$0.value["2ndPlace"] == "Atlético Madrid" &&
$0.value["1stPlace"] == "Real Madrid"
} // Filter Real Madrid defeated Atlético Madrid
years = filteredData
.sorted { $0.key > $1.key } // Sort by year
.map { "\($0.key)" } // Convert year to string
.joined(separator: ", ") // Convert to comma separated single string
print("Real Madrid defeated Atlético Madrid in: \(years)")
print()
let winnersAndChampionships =
Set(Data.map { $0.value["1stPlace"]! }) // Get winners' names
.map { winner in
(winner, Data.filter { $0.value["1stPlace"] == winner }.count)
} // Map for each winner the number of wins
.sorted { $0.1 > $1.1}
print("Number of Champions League's wins per team")
print("------------------------------------------")
winnersAndChampionships.forEach {
print("\($0.0): \($0.1)")
}
答案 1 :(得分:1)
首先,您不需要NSPredicate
来完成如此简单的任务,String.contains()
应该也可以工作。
第二,您可以结合使用mapValues
和compactMapValues
来实现目标:
let searchQuery = "foo"
var data: [Int : [String : String]] = [:]
// map the values of the outer dictionary
let filteredData = data.mapValues {
// we use compactMapValues on the inner dictionary as we want to exclude the values
// that don't match our search
$0.compactMapValues { $0.contains(searchQuery) ? $0 : nil }
}
如果您想进一步优化搜索,例如在内部词典中不包含没有任何匹配项的Int
键,也可以在外部词典中compactMapValues
:< / p>
let filteredData = data.compactMapValues {
let filteredDict = $0.compactMapValues { $0.contains(searchQuery) ? $0 : nil }
return filteredDict.isEmpty ? nil: filteredDict
}