想象兩個陣列:
const array1 = [1,2,3];
const array2 = [2,3,4];
現在,我想獲取這兩個陣列的所有差異并將它們放入兩個新陣列中。一個陣列將用于第一個丟失的所有專案。另一個將用于第二個中缺少的專案。結果看起來像這樣:
const newArray1 = [1];
const newArray2 = [4];
我將如何解決這個問題,最有效的方法是什么?
uj5u.com熱心網友回復:
const array1 = [2,1,3,5,2,1,3,5];
const array2 = [4,3,2,6,7,4,3,2,6,7];
function diff(arr1, arr2) {
const dontAddDuplicates = true;
arr1.sort();
arr2.sort();
let a1 = [];
let a2 = [];
let i = 0;
let j = 0;
while (i < array1.length || j < array2.length) {
if (i >= arr1.length) {
if (!dontAddDuplicates || (a2.length == 0 || a2[a2.length - 1] != arr2[j])) {
a2.push(arr2[j]);
}
j ;
} else if (j >= array2.length) {
if (!dontAddDuplicates || (a1.length == 0 || a1[a1.length - 1] != arr1[i])) {
a1.push(arr1[i]);
}
i ;
} else if (arr1[i] < arr2[j]) {
if (!dontAddDuplicates || (a1.length == 0 || a1[a1.length - 1] != arr1[i])) {
a1.push(arr1[i]);
}
i ;
} else if (arr2[j] < arr1[i]) {
if (!dontAddDuplicates || (a2.length == 0 || a2[a2.length - 1] != arr2[j])) {
a2.push(arr2[j]);
}
j ;
} else {
// Same value, do nothing
i ;
j ;
}
}
return [a1, a2];
}
console.log(diff(array1, array2));
// OUTPUT: [[1, 5], [4, 6, 7]]
這是使用排序的另一個潛在實作,但它具有使 array1 和 array2 以排序方式保留的副作用。排序允許您避免每次都需要重新掃描另一個陣列。如果它們已經排序,那么很好,你可以跳過這一步。如果副作用是一個問題,那么在呼叫 sort 之前使用 array1 和 array2 的深拷貝。
dontAddDuplicates如果您想要重復,請翻轉。我注意到其他實作沒有考慮到這一點,但很容易添加。
運行時間應為: SORT N SORT M N M = SORT N = N LOG N 取決于您的輸入大小和分布 SORT 將是重要的 O 表示法https://www.bigocheatsheet.com/
https://jsfiddle.net/buscgtL2/1/
如果你想在 N M N M = N 時間內完成,你可以使用這個使用哈希映射而不是排序的實作。這對記憶體空間有不利影響。
const array1 = [2,1,3,5,2,1,3,5];
const array2 = [4,3,2,6,7,4,3,2,6,7];
function diff(arr1, arr2) {
let dontAddDuplicates = true;
let a1 = [];
let a2 = [];
let a1hash = {};
let a2hash = {};
for (let i = 0; i < arr1.length; i ) {
a1hash[arr1[i]] = 0;
}
for (let i = 0; i < arr2.length; i ) {
a2hash[arr2[i]] = 0;
}
for (let i = 0; i < arr1.length; i ) {
if (!a2hash.hasOwnProperty(arr1[i])) {
if (!dontAddDuplicates || a1hash[arr1[i]] == 0) {
a1hash[arr1[i]] = 1;
a1.push(arr1[i]);
}
}
}
for (let i = 0; i < arr2.length; i ) {
if (!a1hash.hasOwnProperty(arr2[i])) {
if (!dontAddDuplicates || a2hash[arr2[i]] == 0) {
a2hash[arr2[i]] = 1;
a2.push(arr2[i]);
}
}
}
return [a1, a2];
}
console.log(diff(array1, array2));
//OUTPUT: [[1, 5], [4, 6, 7]]
https://jsfiddle.net/2945y3an/1/
更糟糕的性能是任何演算法,對于每個 N 元素,您掃描陣列 M 以搜索匹配項。這將是 N * M = N^2
uj5u.com熱心網友回復:
像這樣的東西會相對有效,你只需要遍歷兩個陣列。
遍歷第一個陣列并將任何缺失的項添加到第一個 newArray。對第二個陣列重復相同的程序。
如果您只需要遍歷陣列一次,則需要執行類似于下面所做的操作,但只遍歷最長的陣列。
const array1 = [1,2,3];
const array2 = [2,3];
function diff (arr1, arr2) {
const newA1 = [];
const newA2 = [];
arr1.forEach((item, i) => {
let index = arr2.findIndex(it => it === item);
if(index < 0) newA1.push(item);
});
arr2.forEach((item, i) => {
let index = arr1.findIndex(it => it === item);
if(index < 0) newA2.push(item);
});
return [newA1, newA2];
}
console.log(diff(array1, array2));
更有效的方法(僅回圈通過 1 個陣列)。這樣,您選擇最長的陣列,回圈遍歷它,并檢查長陣列的當前項的重復項,如果輔助陣列中的項存在于同一位置,請檢查最長陣列中該項的重復項. 此方法與上述方法類似,但每個回圈只有 1 個。
const array1 = [1,2,3];
const array2 = [3,4,5];
function diff (arr1, arr2) {
const newA1 = [];
const newA2 = [];
let baseArr, secondaryArr;
if(arr1.length > arr2.length) {
baseArr = arr1;
secondaryArr = arr2;
} else {
baseArr = arr2;
secondaryArr = arr1;
}
baseArr.forEach((item, i) => {
const secondaryArrI = secondaryArr.findIndex(it => it === item);
if(secondaryArrI < 0) newA1.push(item)
if(typeof secondaryArr[i] !== "undefined") {
const removeI = baseArr.findIndex(it => it === secondaryArr[i]);
if(removeI < 0) newA2.push(secondaryArr[i]);
}
})
return [newA1, newA2];
}
console.log(diff(array1, array2));
uj5u.com熱心網友回復:
如果你不介意的話, Lodash 的區別
const array1 = [1,2,3];
const array2 = [2,3,4];
console.log(_.difference(array1, array2));
console.log(_.difference(array2, array1));
.as-console-wrapper{min-height: 100%!important; top: 0}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
uj5u.com熱心網友回復:
通過使用Array.filter()和 JavaScript 的Array.includes()方法,您可以用最少的代碼行以非常簡單的方式實作它。
作業演示:
const array1 = [1,2,3];
const array2 = [2,3,4];
const updatedArray1 = array1.filter(item => !array2.includes(item));
const updatedArray2 = array2.filter(item => !array1.includes(item));
console.log(updatedArray1); // [1]
console.log(updatedArray2); // [4]
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/444762.html
標籤:javascript 数组 排序
