从给定的两个列表中,如何从一个列表中提取 Dart 中另一个列表中不可用的所有元素?

From given two lists, how to extract all the elements from one list that are not available in the other list in Dart?

我在 Dart 中有两个列表,如下所示,

  final List availableIssueComponents = [
    {'id': 1, 'componentName': 'Cash Acceptor'},
    {'id': 2, 'componentName': 'Printer'},
    {'id': 3, 'componentName': 'PIN Pad'},
    {'id': 4, 'componentName': 'Key Board'},
    {'id': 5, 'componentName': 'Touch Screen'},
    {'id': 6, 'componentName': 'Computer'},
    {'id': 7, 'componentName': 'Application'},
    {'id': 8, 'componentName': 'Network'},
    {'id': 9, 'componentName': 'Power'},
    {'id': 10, 'componentName': 'Camera'},
    {'id': 11, 'componentName': 'Safe'},
    {'id': 13, 'componentName': 'Screen'},
    {'id': 14, 'componentName': 'Battery'},
    {'id': 15, 'componentName': 'Ports'},
    {'id': 16, 'componentName': 'Application'},
    {'id': 17, 'componentName': 'Safe'},
    {'id': 18, 'componentName': 'Camera'},
    {'id': 19, 'componentName': 'Power'},
    {'id': 20, 'componentName': 'Key Board'},
    {'id': 21, 'componentName': 'PIN Pad'},
    {'id': 22, 'componentName': 'Printer'},
    {'id': 23, 'componentName': 'Computer'},
    {'id': 24, 'componentName': 'Touch Screen'},
    {'id': 25, 'componentName': 'Application'},
    {'id': 26, 'componentName': 'Network'}
  ];

  final List selectedIssueComponents = [
    {'id': 3, 'componentName': 'PIN Pad'},
    {'id': 6, 'componentName': 'Computer'},
    {'id': 19, 'componentName': 'Power'},
  ];

从以上两个列表中,我试图 select availableIssueComponents 中的所有元素,不包括 selectedIssueComponents 中已经可用的元素。

Ex:由于 ID 为 3619 的组件在两个列表中都很常见,因此我想要第三个列表,其中包含除组件之外的所有组件使用 3619.

的 ID

第三个列表应该如下所示,

  final List availableIssueComponents = [
    {'id': 1, 'componentName': 'Cash Acceptor'},
    {'id': 2, 'componentName': 'Printer'},
    {'id': 4, 'componentName': 'Key Board'},
    {'id': 5, 'componentName': 'Touch Screen'},
    {'id': 7, 'componentName': 'Application'},
    {'id': 8, 'componentName': 'Network'},
    {'id': 9, 'componentName': 'Power'},
    {'id': 10, 'componentName': 'Camera'},
    {'id': 11, 'componentName': 'Safe'},
    {'id': 13, 'componentName': 'Screen'},
    {'id': 14, 'componentName': 'Battery'},
    {'id': 15, 'componentName': 'Ports'},
    {'id': 16, 'componentName': 'Application'},
    {'id': 17, 'componentName': 'Safe'},
    {'id': 18, 'componentName': 'Camera'},
    {'id': 20, 'componentName': 'Key Board'},
    {'id': 21, 'componentName': 'PIN Pad'},
    {'id': 22, 'componentName': 'Printer'},
    {'id': 23, 'componentName': 'Computer'},
    {'id': 24, 'componentName': 'Touch Screen'},
    {'id': 25, 'componentName': 'Application'},
    {'id': 26, 'componentName': 'Network'}
  ];

我尝试使用 Sets 来做到这一点,以下是我的方法,

Set availableComponentsSet = Set.from(availableIssueComponents);
Set issueComponentsSet = Set.from(selectedIssueComponents);

Set resultComponents = availableComponentsSet.difference(issueComponentsSet);

但是当登录到控制台时,它 resultComponents 包含所有组件。这不是我想要的。我也试过嵌套的 for 循环,它也没有用。

当使用 Set<Map> 时,组件对象不会被 Set 过滤,因为 Map 是一个引用类型并且被认为是唯一的,除非被比较的两个对象指向相同的实例(如@Pat9RB 评论)。

我会将选定的 ID 映射到列表,然后使用 List#where(fn)

过滤掉这些 ID
final availableIssueComponents = [
  {'id': 1, 'componentName': 'Cash Acceptor'},
  {'id': 2, 'componentName': 'Printer'},
  {'id': 3, 'componentName': 'PIN Pad'},
  {'id': 4, 'componentName': 'Key Board'},
  {'id': 5, 'componentName': 'Touch Screen'},
  {'id': 6, 'componentName': 'Computer'},
  {'id': 7, 'componentName': 'Application'},
  {'id': 8, 'componentName': 'Network'},
  {'id': 9, 'componentName': 'Power'},
  {'id': 10, 'componentName': 'Camera'},
  {'id': 11, 'componentName': 'Safe'},
  {'id': 13, 'componentName': 'Screen'},
  {'id': 14, 'componentName': 'Battery'},
  {'id': 15, 'componentName': 'Ports'},
  {'id': 16, 'componentName': 'Application'},
  {'id': 17, 'componentName': 'Safe'},
  {'id': 18, 'componentName': 'Camera'},
  {'id': 19, 'componentName': 'Power'},
  {'id': 20, 'componentName': 'Key Board'},
  {'id': 21, 'componentName': 'PIN Pad'},
  {'id': 22, 'componentName': 'Printer'},
  {'id': 23, 'componentName': 'Computer'},
  {'id': 24, 'componentName': 'Touch Screen'},
  {'id': 25, 'componentName': 'Application'},
  {'id': 26, 'componentName': 'Network'}
];

final selectedIssueComponents = [
  {'id': 3, 'componentName': 'PIN Pad'},
  {'id': 6, 'componentName': 'Computer'},
  {'id': 19, 'componentName': 'Power'},
];

final selectedIds = selectedIssueComponents.map((component) => component['id']).toList();
final filtered = availableIssueComponents.where((element) => !selectedIds.contains(element["id"])).toList();

print(filtered);

如果您更喜欢使用 Setdifference,您可以创建一组 ID。这将创建一组 int (Set<int>),这是原始类型并允许预期的过滤类型:

final availableIssueComponents = [
  {'id': 1, 'componentName': 'Cash Acceptor'},
  {'id': 2, 'componentName': 'Printer'},
  {'id': 3, 'componentName': 'PIN Pad'},
  {'id': 4, 'componentName': 'Key Board'},
  {'id': 5, 'componentName': 'Touch Screen'},
  {'id': 6, 'componentName': 'Computer'},
  {'id': 7, 'componentName': 'Application'},
  {'id': 8, 'componentName': 'Network'},
  {'id': 9, 'componentName': 'Power'},
  {'id': 10, 'componentName': 'Camera'},
  {'id': 11, 'componentName': 'Safe'},
  {'id': 13, 'componentName': 'Screen'},
  {'id': 14, 'componentName': 'Battery'},
  {'id': 15, 'componentName': 'Ports'},
  {'id': 16, 'componentName': 'Application'},
  {'id': 17, 'componentName': 'Safe'},
  {'id': 18, 'componentName': 'Camera'},
  {'id': 19, 'componentName': 'Power'},
  {'id': 20, 'componentName': 'Key Board'},
  {'id': 21, 'componentName': 'PIN Pad'},
  {'id': 22, 'componentName': 'Printer'},
  {'id': 23, 'componentName': 'Computer'},
  {'id': 24, 'componentName': 'Touch Screen'},
  {'id': 25, 'componentName': 'Application'},
  {'id': 26, 'componentName': 'Network'}
];

final selectedIssueComponents = [
  {'id': 3, 'componentName': 'PIN Pad'},
  {'id': 6, 'componentName': 'Computer'},
  {'id': 19, 'componentName': 'Power'},
];
final availableIds = availableIssueComponents.map((component) => component['id']).toSet();
final selectedIds = selectedIssueComponents.map((component) => component['id']).toSet();
final filteredIds = availableIds.difference(selectedIds);
final filteredComponents = availableIssueComponents.where((element) => filteredIds.contains(element["id"])).toList();

print(filteredComponents);