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

问题描述 投票:1回答:2

几天来我一直在努力解决这个问题,通常我不是在这里提问题的人,但是这次我真的很好奇我将如何解决这个问题。

事实是,我有一个地图,它是假设的赛马优惠券(<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个中选出)的第一场比赛中选择赛马1和赛马2,并在控制台中打印couponData看起来像这样:

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

[这意味着它已将Horse 1和Horse 2添加到两个优惠券中,即使我指定要在第一个优惠券中添加或删除,也就是(activeCoupon = 1)。我在嵌套地图中添加和删除列表是否有误?

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

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

flutter dart hashmap deep-copy
2个回答
0
投票

您实际上没有指定问题中的重要部分,但是通过了解MapList的工作原理,我可以知道问题出在哪里:您没有正确初始化它们。

事实是,MapList指向内存中的位置以及执行以下操作时的位置:

final map1 = {};
final map2 = map1;

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

话虽如此,有一些重要的提示我可以给你:

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

  • 您可以使用List.ofList.of

    copy

  • 映射或列表,但是请注意,这是不是deep复制,这意味着复制[C0 ]将为您not copy列表,这意味着它们仍然相同。
  • 在您的问题中包括与您的问题相关的所有操作-在这里您没有包括唯一相关的部分:Map.of的创建。

阅读Map.of以了解有关复制的更多信息。


浅拷贝的问题

我只想快速举例说明这一点,以确保您明白了:

Map<int, List<int>>

[您可能会认为:“哦,我按照建议使用Map<int, Map<int, List<int>>复制数据。现在应该可以了。”但是,这是一个谬论,因为您仍在地图中复制了[[not列表,因此将发生以下情况:

this Wikipedia article

您可以看到,两个地图中的列表均已更改。如果您还想只复制列表的内容,则需要这样做:
final map1 = {
  1: [1, 2], 
  2: [3, 4],
};

final map2 = Map.of(map1);

这是

深复制
,完整的代码如下所示:

Map.of


0
投票
很难解释我在上下文之外创建的所有变量,但这是我所排除的引起问题的代码行:

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] } 变量在此是当前优惠券的副本,将其作为副本的副本与为其选择了优惠券的标识符(整数)一起放入了couponData中。这是我保留旧数据并将新数据添加到其中的方法。但是,在阅读了关于地图和列表如何工作的说明之后,我现在知道,海峡外复制或使列表彼此相等会使事情搞砸了,应该做些不同的事情,正如creativecreatoror可能未指出的那样。

© www.soinside.com 2019 - 2024. All rights reserved.