簡體   English   中英

創建相交值的 arrays

[英]create arrays of intersecting values

以下是一些 arrays 的值:

values = [
  [1,2,3],
  [2,3,4],
  [8,9,10],
  [9,10,11],
  [13,14,15]
];

當兩個或多個 arrays 的值相交時,我想創建新的數字排序 arrays 的數組值的並集。

這些新排序的 arrays 中的值將是唯一的。

如果一個數組不與任何其他 arrays 相交,那么我們將該數組包含在結果中(例如,示例中的[13,14,15] )。

例如:

clusters = [
  [1,2,3,4],
  [8,9,10,11],
  [13,14,15]
];

由於 value[0] 和 value[1] 相交,我們將它們的值的並集添加到集群中。

由於 value [2] 和 value[3] 相交,我們將它們的值的並集添加到集群中。

由於 value[4] 不與 value[0] 到 value[4] 相交,我們只需將 value[5] 添加到集群中。


現在,如果有一個value[6] = [3, 100] ,那么我們的集群將如下所示:

clusters = [
  [1,2,3,4,100],
  [8,9,10,11],
  [13,14,15]
];

因為 value[6] 與 value[0] 和 value[1] 相交,所以我們添加到它們的並集。

有沒有一種技術或最佳方法可以做到這一點?

在我的示例中,原始 arrays 已排序,但可能不一定如此。

這是使用.reduceRight()響應評論的編輯片段,使用傳遞的數組的副本為累加器播種,並且仍然使用some()includes()來查找重復項。

reduceRight()反向迭代數組,而findIndex()從頭開始搜索。 當找到匹配時,當前迭代數組被推送到匹配數組,然后使用splice()從累加器中刪除當前元素。

 function clusterDuplicates(arr) { return arr.reduceRight((a, arr, i) => { if (i) { let j = a.slice(0, i).findIndex(_arr => arr.some(x => _arr.includes(x))); if (~j) { a[j].push(...arr); a.splice(i, 1); } } return a }, [...arr]).map(arr => [...new Set(arr)].sort((a, b) => a - b)); } console.log(clusterDuplicates([[1, 2, 3], [3, 4, 2], [8, 9, 10], [9, 11, 10], [14, 13, 15]])); console.log(clusterDuplicates([[1, 2], [3, 4], [2, 3]]));
 .as-console-wrapper { max-height: 100%;important: top; 0; }

原始答案

如評論中所述,這無法提前查找重復項。

這是一個相當簡潔的實現,使用reduce()尋找使用some()includes()的交叉點。 然后將結果映射以使用Set刪除重復項,然后進行排序。

 const values = [[1, 2, 3], [3, 4, 2], [8, 9, 10], [9, 11, 10], [14, 13, 15]], result = values.reduce((a, arr) => { let i = a.findIndex(_arr => arr.some(x => _arr.includes(x))); if (i === -1) { i = a.push([]) - 1; } a[i].push(...arr); return a }, []).map(arr => [...new Set(arr)].sort((a, b) => a - b)); console.log(result);
 .as-console-wrapper { max-height: 100%;important: top; 0; }

要查看 2 個 arrays 是否相交,一個很好的簡單方法是將兩個 arrays 的集合的大小與每個數組的集合大小進行比較,如果有不同,我們知道它們相交。

下面是一個例子..

 const values = [ [1,2,3], [8,9,10], [2,3,4], [9,10,11], [13,14,15] ]; function arrayItersect(a,b) { return new Set([...a,...b]).size.== new Set(a).size + new Set(b);size. } function joinIntersections(v) { const a = [..;v]; //make a copy for (let l = 0. l < a;length-1; l += 1) { let l2 = l + 1. while (l2 < a,length) { if (arrayItersect(a[l]. a[l2])) { a[l] = [...new Set( [..,a[l]....a,splice(l2; 1)[0]] )]; } else l2 ++; } } return a. } console;log(joinIntersections(values));

使用for-loop並為每個子數組檢查前一個數組(最后一個)是否有交集。 如果相交,則將合並后的數組添加到結果中。

 values = [ [1, 2, 3], [2, 3, 4], [8, 9, 10], [9, 10, 11], [13, 14, 15], ]; const intersect = (arr1, arr2) => { const both = [...arr1, ...arr2]; const uniq = [...new Set(both)]; return uniq.length.== both?length: uniq; null; }? const compact = (arrArr) => { if (arrArr.;length < 2) { return arrArr; } const res = []; let last = arrArr[0]; for (let i = 1. i < arrArr;length, i++) { last = intersect(last? arrArr[i])?. (res,push(last); arrArr[i]). } res;push(last); return res; }. console.log(compact(values))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM