set.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /**
  2. * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. */
  6. import { iterableToArray } from '../mol-data/util/array';
  7. // TODO use set@@iterator when targeting es6
  8. export namespace SetUtils {
  9. export function toArray<T>(set: ReadonlySet<T>) {
  10. return iterableToArray(set.values());
  11. }
  12. /** Test if set a contains all elements of set b. */
  13. export function isSuperset<T>(setA: ReadonlySet<T>, setB: ReadonlySet<T>) {
  14. let flag = true;
  15. setB.forEach(elem => {
  16. if (!setA.has(elem)) flag = false;
  17. });
  18. return flag;
  19. }
  20. /** Add all elements from `sets` to `out` */
  21. export function add<T>(out: Set<T>, ...sets: ReadonlySet<T>[]): Set<T> {
  22. for (let i = 0; i < sets.length; i++) {
  23. sets[i].forEach(elem => out.add(elem));
  24. }
  25. return out;
  26. }
  27. /** Create set containing elements of both set a and set b. */
  28. export function union<T>(setA: ReadonlySet<T>, setB: ReadonlySet<T>): Set<T> {
  29. const union = new Set(setA);
  30. setB.forEach(elem => union.add(elem));
  31. return union;
  32. }
  33. export function unionMany<T>(...sets: ReadonlySet<T>[]) {
  34. if (sets.length === 0) return new Set<T>();
  35. if (sets.length === 1) new Set(sets[0]);
  36. const union = new Set(sets[0]);
  37. for (let i = 1, il = sets.length; i < il; i++) {
  38. sets[i].forEach(elem => union.add(elem));
  39. }
  40. return union;
  41. }
  42. export function unionManyArrays<T>(arrays: T[][]) {
  43. if (arrays.length === 0) return new Set<T>();
  44. const union = new Set(arrays[0]);
  45. for (let i = 1; i < arrays.length; i++) {
  46. for (const elem of arrays[i]) union.add(elem);
  47. }
  48. return union;
  49. }
  50. /** Create set containing elements of set a that are also in set b. */
  51. export function intersection<T>(setA: ReadonlySet<T>, setB: ReadonlySet<T>): Set<T> {
  52. const intersection = new Set<T>();
  53. setB.forEach(elem => {
  54. if (setA.has(elem)) intersection.add(elem);
  55. });
  56. return intersection;
  57. }
  58. export function areIntersecting<T>(setA: ReadonlySet<T>, setB: ReadonlySet<T>): boolean {
  59. let flag = false;
  60. setB.forEach(elem => {
  61. if (setA.has(elem)) flag = true;
  62. });
  63. return flag;
  64. }
  65. export function intersectionSize<T>(setA: ReadonlySet<T>, setB: ReadonlySet<T>): number {
  66. let count = 0;
  67. setB.forEach(elem => {
  68. if (setA.has(elem)) count += 1;
  69. });
  70. return count;
  71. }
  72. /** Create set containing elements of set a that are not in set b. */
  73. export function difference<T>(setA: ReadonlySet<T>, setB: ReadonlySet<T>): Set<T> {
  74. const difference = new Set(setA);
  75. setB.forEach(elem => difference.delete(elem));
  76. return difference;
  77. }
  78. /** Number of elements that are in set a but not in set b. */
  79. export function differenceSize<T>(setA: ReadonlySet<T>, setB: ReadonlySet<T>): number {
  80. let count = setA.size;
  81. setA.forEach(elem => {
  82. if (setB.has(elem)) count -= 1;
  83. });
  84. return count;
  85. }
  86. /** Test if set a and b contain the same elements. */
  87. export function areEqual<T>(setA: ReadonlySet<T>, setB: ReadonlySet<T>) {
  88. if (setA.size !== setB.size) return false;
  89. let flag = true;
  90. setB.forEach(elem => {
  91. if (!setA.has(elem)) flag = false;
  92. });
  93. return flag;
  94. }
  95. }