从dart列表中提取常见元素

时间:2019-12-20 22:02:49

标签: flutter dart

我有3个列表,例如:

  List l1 = [1, 2, 3, 55, 7, 99, 21];
  List l2 = [1, 4, 7, 65, 99, 20, 21];
  List l3 = [0, 2, 6, 7, 21, 99, 26];

我希望有共同点:

// [7,99,21]

这是我尝试过但无法正常工作的内容:

 List l1 = [1, 2, 3, 55, 7, 99, 21];
 List l2 = [1, 4, 7, 65, 99, 20, 21];
 List l3 = [0, 2, 6, 7, 21, 99, 26];
 List common = l1;

 l2.forEach((element) {
   l3.forEach((element2) {
    if (!common.contains(element) || !common.contains(element2)) {
    common.remove(element);
    common.remove(element2);
    }
   });
 });

print(common);

另外,列表的数量是动态的,所以我希望像这样嵌套它们,我没有递归的经验,所以我做不到,甚至不知道它是否比嵌套循环好。

感谢您的帮助。

6 个答案:

答案 0 :(得分:2)

一种解决方案:

void main() {
  List l1 = [1, 2, 3, 55, 7, 99, 21];
  List l2 = [1, 4, 7, 65, 99, 20, 21];
  List l3 = [0, 2, 6, 7, 21, 99, 26];

  l1.removeWhere((item) => !l2.contains(item));
  l1.removeWhere((item) => !l3.contains(item));

  print(l1);
}

结果:

  

[7,99,21]

如果列表的数量是动态的,那么一种解决方案是对所有列表中的所有出现次数进行计数,并仅保留出现次数等于列表数量的值:

void main() {
  List<List> lists = [
    [1, 2, 3, 55, 7, 99, 21],
    [1, 4, 7, 65, 99, 20, 21],
    [0, 2, 6, 7, 21, 99, 26]
  ];

  Map map = Map();
  for (List l in lists) {
    l.forEach((item) => map[item] = map.containsKey(item) ? (map[item] + 1) : 1);
  }

  var commonValues = map.keys.where((key) => map[key] == lists.length);

  print(commonValues);
}

结果:

  

(7,99,21)

答案 1 :(得分:2)

您不需要嵌套循环或递归。 Dart在Set上有fold个方法和一个非常不错的Lists方法。

main() {
  final lists = [
    [1, 2, 3, 55, 7, 99, 21],
    [1, 4, 7, 65, 99, 20, 21],
    [0, 2, 6, 7, 21, 99, 26]
  ];

  final commonElements =
      lists.fold<Set>(
        lists.first.toSet(), 
        (a, b) => a.intersection(b.toSet()));

  print(commonElements);
}

礼物:

{7, 99, 21}

答案 2 :(得分:1)

用于在项目中复制和粘贴的功能:

List<T> intersection<T>(Iterable<Iterable<T>> iterables) {
  return iterables
    .map((e) => e.toSet())
    .reduce((a, b) => a.intersection(b))
    .toList();
}

final commonElements = intersection(lists);

我想在 Richard Ambler 的回答下将此作为评论,但它失去了格式。

答案 3 :(得分:0)

以防万一,如果您想使用嵌套循环。

 void main() {
  List l1 = [1, 2, 3, 55, 7, 99, 21];
  List l2 = [1, 4, 7, 65, 99, 20, 21];
  List l3 = [0, 2, 6, 7, 21, 99, 26];

  List result = [];

  for (final e1 in l1) {
    for (final e2 in l2) {
      for (final e3 in l3) {
        if (e1 == e2 && e1 == e3) {
          result.add(e1);
        }
      }
    }
  }

  print(result);
}

答案 4 :(得分:0)

使用静态扩展方法的示例:

import 'package:enumerable/enumerable.dart';

void main() {
  final query = l1.intersect(l2).intersect(l3);
  print(query.toList());
}

List l1 = [1, 2, 3, 55, 7, 99, 21];
List l2 = [1, 4, 7, 65, 99, 20, 21];
List l3 = [0, 2, 6, 7, 21, 99, 26];

结果:

[7, 99, 21]

另一种方式(在二维列表的情况下)。
尽管一切都可能取决于算法,但是我认为在特定要求下完成定型可能不会有特殊的困难。

import 'package:enumerable/enumerable.dart';

void main() {
  var result = list.isEmpty
      ? <int>[]
      : list
          .aggregate$1(list.first, (Iterable<int> a, e) => a.intersect(e))
          .toList();

  print(result);
}

var list = [
  [1, 2, 3, 55, 7, 99, 21],
  [1, 4, 7, 65, 99, 20, 21],
  [0, 2, 6, 7, 21, 99, 26],
];

答案 5 :(得分:0)

或者你可以这样做:

  List l1 = [1, 2, 3, 55, 7, 99, 21];
  List l2 = [1, 4, 7, 65, 99, 20, 21];
  List l3 = [0, 2, 6, 7, 21, 99, 26];
  
  List uniqueItemsList = l1
    .toSet()
    .where((x) => l2.toSet().contains(x))
    .where((x) => l3.toSet().contains(x))
    .toList();
  
  print(uniqueItemsList); //[7, 99, 21]