如何从dart中对象列表的列表中找到一个属性对象?

  • 本文关键字:列表 对象 属性 一个 dart dart
  • 更新时间 :
  • 英文 :


你好,我是新来的dart,并试图在列表的列表中通过属性名称找到一个项目。

class Product{
String id;
String title;
Product(this.id,this.title);
}
void main(){

List<List<Product>> allProdcuts=[
//New Prodcuts
[
Product("1","Hammer"),
Product("3","Nails"),
Product("2","Screws"),
],
futureItems,
//Old Prodcuts
[
Product("4","Rock"),
Product("5","Paper"),
Product("6","Scissor"),
],
//Rare Items
[
Product("7","Plank"),
Product("8","Wires"),
Product("9","Box"),
],
];
print(allProdcuts.where((itemsList)=>itemsList.contains((product)=>product.title='Wires')));  
//Returns ()

}

我已经尝试使用一个单一的列表:

List<Product> futureItems=     [
Product("101","Galactic Hammer"),
Product("301","Galactic Nails"),
Product("201","Galactic Screws"),
];
print(newProduct.firstWhere((p)=>p.title=='Hammer'));
//Instance of 'Product'

也试过这个:

print(allProdcuts.map((itemList)=>itemList.firstWhere((p)=>p.title=='Nails')));
// Bad state: No elementError: Bad state: No element.

但是有一个标题为'Nails'的元素。我不明白我做错了什么。

您在每个列表中调用itemList.firstWhere((p)=>p.title=='Nails'),也没有标题为"Nails"的元素。因为如果没有匹配的值,firstWhere就会抛出,所以它会对三个列表中的两个进行抛出。此外,在示例中,itemsList.contains(...)不接受回调,因此您只是检查函数是否在列表中,它不在列表中。您可能想使用any,但它不会解决这里的问题。

为了更有效地做到这一点,我可能会创建辅助函数:

Product findByTitle(List<List<Product>> allProducts, String title) {
for (var products in allProducts) {
for (var product in products) {
if (product.title == title) return product;
}
}
// Or return `null`.
throw ArgumentError.value(title, "title", "No element with that title");
}

中间的return允许您在匹配时跳过双迭代,这对于firstWhere/map/forEach等来说很难做到。

另一个解决方案是:

var product = allProducts.expand((l) => l.where((p) => p.title == title)).first;

查找具有给定标题的所有产品,并将它们平展到单个可迭代对象中,然后选择第一个(如果有的话)。因为可迭代对象是惰性的,它实际上会在第一次匹配时停止。

有很多方法可以解决这个问题。

一个例子是使用forEach()方法:
allProdcuts.forEach(
(List<Product> l)=>l.forEach(
(Product p){
if (p.title=="Nails") 
print(p.id);
}
)
);

for每个方法接收一个函数,并将该函数应用于列表中的每个元素。如果您有一个列表的列表,您可以这样做两次,以便将函数应用于子列表的每个元素。

上面的代码输出3,这是期望的结果。

另一个解决方案是先将列表平铺,这样以后就可以更容易地进行搜索。

print(allProdcuts.any((innerListOfProducts) =>
innerListOfProducts.any((product) => product.title == 'Wires')));

如果'Wires'在内部列表中,此代码将返回true,否则返回false。

最新更新