Flutter:删除列表中的项目反映另一个列表



我有以下颤振代码,我有一个列表,我们称之为list1,我将这个列表的值对应到另一个列表list2

当我从list1中删除一个元素时,它会自动从list2中删除!

有一个最小的代码来重现这个问题。我无法理解这种奇怪的行为,有人能向我解释一下吗?

我想做的是从list1中删除一个项目,但保持list2原样。

这是代码:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
void main() => runApp(EmptyFile());
class EmptyFile extends StatefulWidget {
final list1 = ["1", "2", "3"];
EmptyFile({Key? key}) : super(key: key);
@override
_EmptyFileState createState() => _EmptyFileState(list1);
}
class _EmptyFileState extends State<EmptyFile> {
List<String> list1 ;
List<String> list2 = [];
_EmptyFileState(this.list1) {
list2 = list1;
}
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
title: const Text('Example App'),
),
body:
Container(
child: RaisedButton(
onPressed: () {
print("list1.last ${list1.last}"); // the result is: list1.last 3
list2.remove("3");                 // here I delete from list2 (list TWO)
print("list1.last ${list1.last}"); // the result is: list1.last 2 . Here an item from list ONE has been deleted!!!
},
child: Text('delete last Item'),
),
)
));
}
}

您可以从这里在线运行代码:https://dartpad.dev/81d0a66ac7c46258df7847fdc7a10e96?null_safety=true

显然,dart通过引用复制列表。因此,要将一个列表的值复制到另一个列表,请使用以下代码:

list2  = List.from(list1);

而不是:

list2 = list1;

通过此

list2 = list1;

您实际上并不是在复制list1。这也是分配给list2的相同列表。

所以你需要改变这个。

list2 = [...list1];

我也遇到过同样的问题。我在GetX状态管理的帮助下从api获取嵌套对象数据。

Hasan Mhd Amin给出的公认答案是绝对正确的。但在嵌套对象(列表的嵌套列表(中没有按需工作。

留意MyCode

List<BrandWithModel> original = [];
List<BrandWithModel> selectedModels = [];
// controllers
final generalController = Get.find<GeneralController>();
@override
void initState() {
WidgetsBinding.instance.addPostFrameCallback(
(_) {
if (generalController.isRefreshForBrandWithModel.value) {
generalController.brandWithModel(brandIDs: [3, 4]).then(
(value) => initValues(),
);
} else {
initValues();
}
},
);
super.initState();
}
void initValues() {
original = List<BrandWithModel>.from(generalController.models);
selectedModels = List<BrandWithModel>.from(generalController.models);
// remove model from selectedModels
selectedModels.forEach(
(element) {
element.model.clear();
},
);
if (mounted) setState(() {});
}

当我从selectedModels中删除数据时,它也将从原始模型中删除。

经过深入研究,我发现了这一点。

/*
* => When you create a new list using List<BrandWithModel>.from(generalController.models),
* it creates a new list object, but the individual elements within the list are still references to the same objects in memory.
* Therefore, modifying an element in selectedModels will also affect the corresponding element in original because they are essentially the same object.
* =>  If you want to have separate lists with independent data,
*   you need to create new instances of BrandWithModel objects for selectedModels.
*   One way to achieve this is by creating a deep copy of each element when initializing the selectedModels list.
*   Here's an example of how you can modify the initValues() method to create a deep copy
*/

我在那里找到了如下的解决方案

//Used this 
selectedModels = generalController.models
.map(
(model) => BrandWithModel.fromJson(   // json to modelmethod
model.toJson(),                     // model to json method
),
)
.toList();
// instead of
selectedModels = List<BrandWithModel>.from(generalController.models);
//  remain are same as above.

您可以使用排列操作:

list2 = [...list1];

这应该允许任何可迭代对象复制值,而不是使用引用。

最新更新