在嵌套地图内的列表中添加和删除值会影响所有嵌套地图

空间编码器

我已经为这个问题苦苦挣扎了好几天了,通常我不是在这里问问题的人,但是这次我真的很好奇我将如何解决这个问题。

问题是,我有一个地图,它是假设的赛马优惠券(<int,的“唯一标识符”,以及代表每个比赛中的假设种族和马​​匹的(键:用于列)和(值:用于行)的映射,因此,该变量看起来像这样:(Map<int, Map<int, List<int>>> couponData = new Map();)。

例如,打印出这样的内容:

{1: {0: [1,6], 1: [], 2: [2,6], 3: [], 4: [3,6,7,8], 5: [], 6: []}}

或者更确切地说:

{Coupon1: {Race1: [Horse1,Horse6], Race2: [], Race3: [Horse2,Horse6], Race4: [], Race5: [Horse3,Horse6,Horse7,Horse8], Race6: [], Race7: []}}

现在一切正常。但是,我的问题是,当我在每个种族(或列表)中添加新马匹或将它们删除时。

如果我有多个优惠券,并且只想换另一张优惠券中的一匹马,则会影响所有优惠券,而不仅仅是我当前选择的优惠券。因此,代码如下所示:

int activeCoupon = 1;

if (!couponData[activeCoupon][raceNumber].contains(horseNumber + 1)) {
  couponData[activeCoupon][raceNumber].add(horseNumber + 1);
} else {
  couponData[activeCoupon][raceNumber].remove(horseNumber + 1);
}

现在,在我的第一张优惠券(共2张)的第一场比赛中选择Horse 1和Horse 2,并在控制台中打印couponData,如下所示:

{1: {0: [1, 2], 1: [], 2: [], 3: [], 4: [], 5: [], 6: []}, 2: {0: [1, 2], 1: [], 2: [], 3: [], 4: [], 5: [], 6: []}}

这意味着即使我指定要在第一个优惠券中添加或删除,也就是(activeCoupon = 1,它都已将Horse 1和Horse 2添加到两个优惠券中我在嵌套地图中添加和删除列表时我做错了什么?

我尝试了许多不同的方法,例如进入.forEach并手动添加和删除与各个种族和赛马相关联的值,但结果相同。

任何有关我将如何以不同方式进行操作的线索?干杯

创造者或可能不是

您实际上并未在问题中指定重要部分,但是通过了解Maps和Lists的工作原理,我可以知道问题出在哪里:您在错误地初始化它们。

问题是,MapList指向内存中的地方,当你做的东西像下面这样:

final map1 = {};
final map2 = map1;

现在,您将有两个指向内存中相同位置的地图,因此编辑map1也会影响map2

话虽如此,我可以为您提供一些重要提示:

  • 构造您的(可能不是理想的优惠券赛马数据结构)时,请确保您将每个条目分配给地图的实际上是不同的,即不要一次创建6个比赛,然后将其“复制”到另一个优惠券中,但为每张优惠券创建它。

  • 你可以用List.ofMap.of复制地图或列表,但要知道,这是不是一个拷贝,这意味着复制Map<int, List<int>>无法复制你的列表,这意味着他们仍然是相同的。

  • 在问题中包括与您的问题相关的所有操作-在这里,您没有包括唯一相关的部分:创建您的Map<int, Map<int, List<int>>

阅读此Wikipedia文章以了解有关复制的更多信息。


浅拷贝的问题

我只是想快速说明一下,以确保您得到以下信息:

final map1 = {
  1: [1, 2], 
  2: [3, 4],
};

final map2 = Map.of(map1);

您可能会想:“哦,我按照建议使用来复制数据Map.of。现在应该可以了。” 但是,这是一个谬论,因为您在地图中仍然有您的列表,这些列表没有被复制,因此将发生以下情况:

map1[1].remove(2);

print(map1[1]); // [1]
print(map2[1]); // [1]

如您所见,两个地图中的列表均已更改。如果您还希望仅复制列表的内容,则需要这样做:

final map2 = {};

for (final entry in map1.entries) {
  map2[entry.key] = List.of(entry.value);
}

这是一个深层副本,完整的代码如下所示:

void main() {
  final map1 = {
    1: [1, 2],
    2: [3, 4],
  };

  final map2 = {};

  for (final entry in map1.entries) {
    map2[entry.key] = List.of(entry.value);
  }

  map1[1].remove(2);

  print(map1[1]); // [1]
  print(map2[1]); // [1, 2]
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章