Simple Map here:
Map map = Map<int, String>{};
我可以填充它:
map = {1: 'c', 2: 'dart', 3: 'flutter'};
这里我需要指定一个KEY。我想知道如何得到一把自动钥匙。
我不能使用map。长度,因为每当我删除例如第二个项目(2)时,第三个将保持3和映射。长度将覆盖该键。
作为@eamirho3ein的答案,我尝试了这个:
//& Maps
Map map = <int, Ingredient>{};
Map<int, T> addToMap<T>(Map<int, T> map, T newItem) {
var list = map.entries.map((e) => e.value).toList();
list.add(newItem);
var newIndex = 1;
return Map.fromIterable(list,
key: (item) => newIndex++, value: (item) => item);
}
Map<int, Ingredient> result = addToMap<Ingredient>(
map, //Error here
Ingredient(
name: "Pizza",
kcal: 100,
carbohydrates: 50,
proteins: 35,
lipids: 23,
fibers: 12,
date: DateTime.now(),
bottomTabIndex: 0,
leftTabIndex: 0));
但是我在map(指示)上收到这个错误:
参数类型'Map<dynamic,>'不能赋值给参数类型'Map<int,>'.
这是我的简单类:
class Ingredient {
String? name;
int? kcal;
int? carbohydrates;
int? proteins;
int? lipids;
int? fibers;
int? leftTabIndex;
int? bottomTabIndex;
DateTime? date;
Ingredient(
{this.name,
this.kcal,
this.carbohydrates,
this.proteins,
this.lipids,
this.fibers,
this.leftTabIndex,
this.bottomTabIndex,
this.date});
}
您可以使用此函数删除映射中的项并自动生成新键:
Map<int, T> removeFromMap<T>(Map<int, T> map, int index) {
var list = map.entries.map((e) => e.value).toList();
list.removeAt(index);
var newIndex = 1;
return Map.fromIterable(list,
key: (item) => newIndex++, value: (item) => item);
}
你可以这样使用:
var result = removeFromMap<String>({1: 'c', 2: 'dart', 3: 'flutter'}, 1);
print("result = $result"); //result = {1: c, 2: flutter}
如果你想要添加新项目:
Map<int, T> addToMap<T>(Map<int, T> map, T newItem) {
var list = map.entries.map((e) => e.value).toList();
list.add(newItem);
var newIndex = 1;
return Map.fromIterable(list,
key: (item) => newIndex++, value: (item) => item);
}
,并像这样命名:
var result = addToMap<String>({1: 'c', 2: 'dart', 3: 'flutter'}, 'B');
print("result = $result"); //result = {1: c, 2: dart, 3: flutter, 4: B}
您可以使用一个递增的index
键,它将在每次调用中始终与其他键不同,并将其包装在autoKey()
方法中,如下所示:
int index = 0;
autoKey() {
return ++index;
}
Map<int, String> map = {};
map = {autoKey(): 'c', autoKey(): 'dart', autoKey(): 'flutter'};
print(map); {1: c, 2: dart, 3: flutter}
也许我应该使用一个函数:
int getNewKey(Map map) {
if (map.isEmpty) {
return 0; // or 1, this is the first item I insert
} else {
return map.keys.last + 1;
}
}
当我要向映射中添加内容时使用
{getNewKey(map): 'c', getNewKey(map): 'dart', getNewKey(map): 'flutter'}
如果有问题请告诉我:-|
通过这种方式,我将永远不会覆盖一个只有增量的键。
请注意:不能直接使用
{(map.keys.last + 1) : 'c', (map.keys.last + 1) : 'dart', (map.keys.last + 1) : 'flutter'}
因为如果Map为空将会产生错误
如果您有一个使用连续的、基于整数的键的Map
,您应该问自己是否应该使用List
来代替,然后您不需要自己管理键。
如果你必须使用Map
,因为某些API需要它,你仍然可以从List
开始,然后使用List.asMap
来轻松转换它:
var map = [
'c',
'dart',
'flutter',
].asMap();
print(map); // Prints: {0: c, 1: dart, 2: flutter}
注意,List.asMap
返回一个不可修改的视图,所以如果您希望允许更改,则需要创建一个副本:
var map = Map.of([
'c',
'dart',
'flutter',
].asMap());
如果必须让您的Map
键是从1开始的整数,而不是0,那么您可以插入一个虚拟元素(并在需要时稍后删除它):
var map = Map.of([
'',
'c',
'dart',
'flutter',
].asMap())
..remove(0);
print(map); // Prints: {1: c, 2: dart, 3: flutter}
另一种方法是,您可以使用class
作为永远不等于使用hashCode
的键,如下所示:
class nonEqualKey {
@override
int get hashCode => 0;
@override
operator ==(covariant nonEqualKey other) {
return other.hashCode != hashCode;
}
@override
toString() {
return "unique";
}
}
Map map = {};
map = {nonEqualKey(): 'c', nonEqualKey(): 'dart', nonEqualKey(): 'flutter'};
print(map); // {unique: c, unique: dart, unique: flutter}
这里我重写了hashCode
,所以它总是0
,然后我重写了==
运算符,所以如果对象有不同的hashCode
,那么它们可以相等,这是不可能的,因为0!=0
总是false
。
即使您使用相同的class
构造函数,它们也永远不会相同,因此,它允许您随心所欲地使用它,而无需为您在Map
上执行的每个操作处理它