如何根据另一个集合的元素对集合进行特定排序?

时间:2020-08-26 03:46:03

标签: flutter dart

假设我们有2套

void main() {
  Set set1 = {'mario', 'paper', 'is not bad'};
  
  Set set2 = {'paper', 'is not bad'};
  }

我正在尝试按照set2的顺序对set1进行排序,以便可以设置set1

set1 = {'paper', 'is not bad', 'mario'};

编辑:不需要设置。可以使用列表。

我该怎么做?

3 个答案:

答案 0 :(得分:1)

实际上,如果您从最基础的角度出发,那将非常简单,而不是在日常编程中依靠列表/比较器多年/数十年的使用。请记住,合并和相交的顺序很重要:

void main() {
    Set set1 = {'luigi', 'mario', 'paper', 'is not bad', 'coin', 'castle'};
    Set set2 = {'paper', 'is not bad', 'coin', 'luigi'};
    Set sortedSet = set2.union(set1).intersection(set1);
    sortedSet.forEach((element) => print(element));
}

-

编辑(OP提出了一个子问题:他将如何处理列表而不是集合):

就像其他人已经指出的那样-Set是定义明确且不同的对象的集合,另一方面,List可以具有重复项,因此不一定是Set(math),因此,ergo合并/相交不再可用。 / p>

现在,您要处理一个以List开头的列表,就可以“不要重新发明轮子”,并可以使用常见的List函数,例如sort,compare,inverse。

但是现在我们遇到了其他许多情况。例如,如果list1的元素多于list2的元素,那么其中一些多余的元素将被重复而不进行排序。在下面,您会发现4个函数处理不同的问题:

void main() {

  /* fn1(); 
     * Probably what you are looking for #1.
     * All elements that are not present in list2 will appear at the end of list 1
     * also notice that those extra elements will be sorted as well in order of appearance in list1
     * [mario, luigi, luigi, mushroom, mushroom, castle]
  */
  void fn1() {
    List<String> list1 = ['luigi','mario','mushroom','luigi','castle','mushroom'];
    List<String> list2 = ['mario', 'luigi', 'coin'];

    List<String> list2Reveresed = list2.reversed.toList();
    list1.sort((a, b) => list1.indexOf(a).compareTo(list1.indexOf(b)));
    list1.sort((a, b) => list2Reveresed.indexOf(b).compareTo(list2.indexOf(a)));
    print(list1);
  }

  /* fn2(); 
     * Probably what you are looking for #2.
     * All elements that are not present in list2 will appear at the end of list 1
     * also notice that those extra elements will be sorted as well in alphabetical order
     * [mario, luigi, luigi, castle, mushroom, mushroom]
  */
  void fn2() {
    List<String> list1 = ['luigi','mario','mushroom','luigi','castle','mushroom'];
    List<String> list2 = ['mario', 'luigi', 'coin'];

    List<String> list2Reveresed = list2.reversed.toList();
    list1.sort();
    list1.sort((a, b) => list2Reveresed.indexOf(b).compareTo(list2.indexOf(a)));
    print(list1);
  }

  /* fn3()
     * Probably not what you are looking for.
     * All elements that are not present in list2 will appear at the end of list 1
     * also notice that those extra elements will not be sorted.
     * [mario, luigi, luigi, mushroom, castle, mushroom]
  */
    void fn3() {
    List<String> list1 = ['luigi','mario','mushroom','luigi','castle','mushroom'];
    List<String> list2 = ['mario', 'luigi', 'coin'];

    List<String> list2Reveresed = list2.reversed.toList();
    list1.sort((a, b) => list2Reveresed.indexOf(b).compareTo(list2.indexOf(a)));
    print(list1);
  }

  /* fn4() 
     * Least probable to be what you are looking for.
     * All elements that are not present in list2 will appear at the start of list 1,
     * also notice that those extra elements will not be sorted.
     * [mushroom, castle, mushroom, mario, luigi, luigi]
  */
  void fn4() {
    List<String> list1 = ['luigi','mario','mushroom','luigi','castle','mushroom'];
    List<String> list2 = ['mario', 'luigi', 'coin'];

    list1.sort((a, b) => list2.indexOf(a).compareTo(list2.indexOf(b)));
    print(list1);
  }

  fn1();
  fn2();
  fn3();
  fn4();
}  

PS在进行优化之前,您应该始终清楚了解最终结果。您还应该知道这些列表可能有多长,如果它们将变得很大,那么应该进行优化,但是如果它们相对较短,那么优化将纯粹浪费开发时间。 / p>

答案 1 :(得分:0)

您应该将集合转换为列表,因为HashSet在Flutter中是无序的,因此您可以在this package中查找有序集合。在这里,您去了:

void main() {
  Set set1 = {'mario', 'paper', 'omg', 'is not bad', 'good'};
  
  Set set2 = {'paper', 'is not bad', 'omg'};

  var list1 = set1.toList();
  
  var list2 = set2.toList();
  
  
  var result = 
     list1.where((e) => list2.contains(e)).toList() // Get all common items
     ..sort((a, b) => list2.indexOf(a) - list2.indexOf(b)) // Sort common items based on list2 ordering
     ..addAll(list1.where((e) => !list2.contains(e))); // Add the rest of the items
  
  print(result); // [paper, is not bad, omg, mario, good]
}

答案 2 :(得分:0)

如果您关心订单,通常会使用Set,但是如果您确实想要,则可以:

  1. 计算set2.intersection(set1)以查找两组中的所有项目。我相信生成的Set应该保留set2的顺序。

  2. 计算set1.difference(set2)来查找set1中所有的项目,而不是set2中的所有项目。

  3. 将步骤2的结果追加到步骤1的结果。

set1 = {...set2.intersection(set1), ...set1.difference(set2)};