Dart Map键,获得唯一键



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上执行的每个操作处理它

相关内容

  • 没有找到相关文章

最新更新