I want to filter out a list in Flutter/dart which has nested objects. I want to filter out the list based on the name property both with in the parent object and the child object subNames.
Below is the code that I have come up with, which gives me duplicates, is there a better way to solve this?
var rawData = [{
"name": "Testing 123",
"subNames": [{
"name": "Subtesting 123"
}]
},
{
"name": "Testing 456",
"subNames": [{
"name": "Subtesting 456"
}]
},
{
"name": "Testing 456",
"subNames": []
}
]
final results = [
...rawData
.where((m) =>
m.name.toLowerCase().contains('subtesting 123'))// or Testing 123
.toList(),
...rawData
.where((m) => m.subNames
.where((s) =>
s.name.toLowerCase().contains('subtesting 123')) // or Testing 123
.isNotEmpty)
.toList()
];
Expected output:
//Results
[{
"name": "Testing 123",
"subNames": [{
"name": "Subtesting 123"
}]
},
]
CodePudding user response:
First of all, it's better to use Class models and typed variables over json or dynamic nested types. Using this approach we can implement our logic easier. Here is a sample:
const rawData = [
{
"name": "Testing 123",
"subNames": [
{"name": "Subtesting 123"}
]
},
{
"name": "Testing 456",
"subNames": [
{"name": "Subtesting 456"}
]
},
{"name": "Testing 456", "subNames": []}
];
class Model {
String name;
List<SubNames> subNames;
Model({this.name, this.subNames});
Model.fromJson(Map<String, dynamic> json) {
name = json['name'];
if (json['subNames'] != null) {
subNames = <SubNames>[];
json['subNames'].forEach((v) {
subNames.add(new SubNames.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['name'] = this.name;
if (this.subNames != null) {
data['subNames'] = this.subNames.map((v) => v.toJson()).toList();
}
return data;
}
}
class SubNames {
String name;
SubNames({this.name});
SubNames.fromJson(Map<String, dynamic> json) {
name = json['name'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['name'] = this.name;
return data;
}
}
void main() {
List<Model> testModelList = rawData.map((e) => Model.fromJson(e)).toList();
final result = testModelList.where((element) =>
element.name.toLowerCase().contains('subtesting 123') ||
element.subNames
.any((sub) => sub.name.toLowerCase().contains('subtesting 123')));
print('result.length : ${result.length}');
result.forEach((element) {
print(element.toJson());
});
}
You can run this sample see the result.
CodePudding user response:
Try changing your results to the following
final results = [
...rawData
.where((m) =>
m.name.toLowerCase().contains('subtesting 123')
|| m.subNames
.where((s) =>
s.name.toLowerCase().contains('subtesting 123')).toList().isNotEmpty)
.toList(),
];
I'm assuming here you are parsing your rawData so you are able to use m.names
instead of m['names']