2016-05-19 6 views
6

Tôi biết về this question, simplest code for array intersection nhưng tất cả các giải pháp cho rằng số lượng mảng là hai, không thể chắc chắn trong trường hợp của tôi.Cách tính điểm giao nhau của nhiều mảng trong JavaScript? Và [equals: function] có nghĩa là gì?

Tôi có số div trên trang có dữ liệu chứa mảng. Tôi muốn tìm các giá trị chung cho tất cả các mảng. Tôi không biết có bao nhiêu div/mảng tôi sẽ có trước. Cách tốt nhất để tính giá trị chung cho tất cả các mảng là gì?

var array1 = ["Lorem", "ipsum", "dolor"]; 
var array2 = ["Lorem", "ipsum", "quick", "brown", "foo"]; 
var array3 = ["Jumps", "Over", "Lazy", "Lorem"]; 
var array4 = [1337, 420, 666, "Lorem"]; 
//Result should be ["Lorem"]; 

Tôi tìm thấy giải pháp khác ở nơi khác, sử dụng Underscore.js.

var arrayOfArrays = [[4234, 2323, 43], [1323, 43, 1313], [23, 34, 43]]; 
_.intersection.apply(_, arrayOfArrays) 
//Result is [43] 

Tôi đã thử nghiệm điều này với dữ liệu giả đơn giản ở cuối của tôi và có vẻ như nó hoạt động. Nhưng đối với một số lý do, một số các mảng Tôi đang sản xuất, trong đó chứa các chuỗi đơn giản, cũng tự động bao gồm một giá trị gia tăng, "bằng: chức năng":

["Dummy1", "Dummy2", "Dummy3", equals: function] 

Và bất cứ khi nào tôi sử dụng phương pháp Underscore.js ngã tư, trên một mảng các mảng, tôi luôn nhận được [equals: function] trong các công cụ dev, và không - nếu "Dummy3" là phổ biến cho tất cả các mảng - ["Dummy3"].

Vì vậy, TL; DR có giải pháp khác cho mảng giao cắt phù hợp với trường hợp của tôi không? Và bất cứ ai có thể giải thích những gì [bằng: chức năng] có nghĩa là ở đây? Khi tôi mở rộng mục trong các công cụ dev, nó tạo ra một mảng trống và một danh sách các phương thức có sẵn trên các mảng (pop, push, shift etc), nhưng các phương thức này đều bị mờ đi, trong khi equals: function được tô sáng.

+0

Ví dụ về Underscore.js có vẻ hơi gây nhầm lẫn? Mảng cuối cùng không chứa 43. – Arg0n

+0

kk Tôi sẽ sửa lỗi này: s – Gaweyne

+0

Bạn có một ',' thiếu ở cuối 'mảng2'. Tôi vừa thử sử dụng '_.intersection (array1, array2, array3, array4)' trong giao diện điều khiển lodash.com và nó hoạt động trở lại '" Lorem "' –

Trả lời

3

tôi đã viết một hàm helper cho việc này:

function intersection() { 
    var result = []; 
    var lists; 

    if(arguments.length === 1) { 
    lists = arguments[0]; 
    } else { 
    lists = arguments; 
    } 

    for(var i = 0; i < lists.length; i++) { 
    var currentList = lists[i]; 
    for(var y = 0; y < currentList.length; y++) { 
     var currentValue = currentList[y]; 
     if(result.indexOf(currentValue) === -1) { 
     var existsInAll = true; 
     for(var x = 0; x < lists.length; x++) { 
      if(lists[x].indexOf(currentValue) === -1) { 
      existsInAll = false; 
      break; 
      } 
     } 
     if(existsInAll) { 
      result.push(currentValue); 
     } 
     } 
    } 
    } 
    return result; 
} 

Sử dụng nó như thế này:

intersection(array1, array2, array3, array4); //["Lorem"] 

Hoặc như thế này:

intersection([array1, array2, array3, array4]); //["Lorem"] 

Full đang here

UPDATE 1

Một thực hiện hơi nhỏ here sử dụng filter

+0

Cảm ơn vì điều này. Tôi có thể theo dõi nó và nó hoạt động với dữ liệu giả buuuut ... Tôi không có các mảng riêng biệt được lưu trữ trong các biến như array1, và array2, và array3, bởi vì tôi không biết có bao nhiêu div trên trang trước . Tại thời điểm này tôi phải lặp qua chúng và đẩy chúng vào một mảng container khác. Vì vậy, tôi chỉ có thể thực hiện giao lộ (arrayContainingArrays) sẽ không hoạt động với mã của bạn. Điều đó nói rằng đây là một giải pháp tốt trong JavaScript vanilla mà người khác có thể sử dụng. – Gaweyne

+0

@Gaweyne Xem ví dụ cập nhật hoạt động theo cả hai cách. – Arg0n

+0

: O Ok! Hãy cho tôi 5 phút ish Tôi sẽ cố gắng này ra – Gaweyne

1

Mã của bạn với _lodash đang làm việc tốt.

Như bạn có thể nói trong this fiddle:

mã này:

var arrayOfArrays = [[4234, 2323, 43], [1323, 43, 1313], [23, 34, 43]]; 
var a = _.intersection.apply(_, arrayOfArrays); 
console.log(a); 
console.log(a.length); 

sẽ có đầu ra:

[42] 
1 

Có lẽ bạn thấy

bằng: chức năng

vì bạn đang sử dụng loại trình gỡ lỗi.

Cố gắng chỉ in các mảng với console.log, bạn sẽ chỉ nhận được 42.

+0

Khi bạn nói sử dụng một số loại trình gỡ rối, ý của bạn là gì? Công cụ dành cho Chrome? Kết quả lạ mà tôi nhận được là khi tôi in mảng bằng console.log. Nó có thể có thể là một cái gì đó khác ở cuối của tôi can thiệp mà tôi chỉ không thể nhìn thấy được nêu ra. : s – Gaweyne

+0

Bạn có thể đăng console.log() của kết quả không? – Ygalbel

+0

Tôi mở cửa sổ, hai div trên trang. Nó lặp qua chúng và kết hợp các mảng thành một mảng duy nhất.Bảng điều khiển ghi lại kết quả: [bằng, chức năng] "mảng của mảng kết hợp" > 0: Array [3] > 1: Array [11] có giá trị phổ biến ở cả hai mảng nhưng sử dụng phương pháp giao trả về này : Mảng [0] độ dài: 0 > _proto_: Mảng [0] Không thể chụp màn hình giống như trên máy ngoại tuyến. – Gaweyne

4

này có thể được thực hiện khá ngắn gọn nếu bạn thích sử dụng một số đệ quy và cú pháp ES2015 mới:

const array1 = ["Lorem", "ipsum", "dolor"]; 
 
const array2 = ["Lorem", "ipsum", "quick", "brown", "foo"]; 
 
const array3 = ["Jumps", "Over", "Lazy", "Lorem"]; 
 
const array4 = [1337, 420, 666, "Lorem"]; 
 

 
const arrayOfArrays = [[4234, 2323, 43], [1323, 43, 1313], [23, 34, 43]]; 
 

 
// Filter xs where, for a given x, there exists some y in ys where y === x. 
 
const intersect2 = (xs,ys) => xs.filter(x => ys.some(y => y === x)); 
 

 
// When there is only one array left, return it (the termination condition 
 
// of the recursion). Otherwise first find the intersection of the first 
 
// two arrays (intersect2), then repeat the whole process for that result 
 
// combined with the remaining arrays (intersect). Thus the number of arrays 
 
// passed as arguments to intersect is reduced by one each time, until 
 
// there is only one array remaining. 
 
const intersect = (xs,ys,...rest) => ys === undefined ? xs : intersect(intersect2(xs,ys),...rest); 
 

 
console.log(intersect(array1, array2, array3, array4)); 
 
console.log(intersect(...arrayOfArrays)); 
 

 
// Alternatively, in old money, 
 

 
var intersect2ES5 = function (xs, ys) { 
 
    return xs.filter(function (x) { 
 
     return ys.some(function (y) { 
 
      return y === x; 
 
     }); 
 
    }); 
 
}; 
 
    
 
// Changed slightly from above, to take a single array of arrays, 
 
// which matches the underscore.js approach in the Q., and is better anyhow. 
 
var intersectES5 = function (zss) { 
 
    var xs = zss[0]; 
 
    var ys = zss[1]; 
 
    var rest = zss.slice(2); 
 
    if (ys === undefined) { 
 
     return xs; 
 
    } 
 
    return intersectES5([intersect2ES5(xs, ys)].concat(rest)); 
 
}; 
 

 
console.log(intersectES5([array1, array2, array3, array4])); 
 
console.log(intersectES5(arrayOfArrays));

+0

Hunh. Không bao giờ đi qua const hoặc nghỉ ngơi trước đây. Tôi nên đọc thêm về ECMAScript 6 trước khi chủ nhân của tôi thay thế tôi bằng một robot: o – Gaweyne

0

Đối với bất kỳ ai bị lẫn lộn bởi điều này trong tương lai,

_.intersection.apply(_, arrayOfArrays) 

Thực tế là cách thanh lịch nhất để thực hiện việc này. Nhưng:

var arrayOfArrays = [[43, 34343, 23232], [43, 314159, 343], [43, 243]]; 
arrayOfArrays = _.intersection.apply(_, arrayOfArrays); 

Sẽ không hoạt động! Phải làm

var differentVariableName = _.intersection.apply(_,arrayOfArrays); 
0

Lodash tinh khiết:

_.keys(_.pickBy(_.groupBy(_.flatten(arrays)), function (e) {return e.length > 1})) 

Lodash với js đồng bằng:

var elements = {}, duplicates = {}; 
_.each(arrays, function (array) { 
    _.each(array, function (element) { 
     if (!elements[element]) { 
      elements[element] = true; 
     } else { 
      duplicates[element] = true; 
     } 
    }); 
}); 
_.keys(duplicates); 
1

Sử dụng một sự kết hợp của những ý tưởng từ một số người đóng góp và sự tốt lành ES6 mới nhất, tôi đến

const array1 = ["Lorem", "ipsum", "dolor"]; 
 
const array2 = ["Lorem", "ipsum", "quick", "brown", "foo"]; 
 
const array3 = ["Jumps", "Over", "Lazy", "Lorem"]; 
 
const array4 = [1337, 420, 666, "Lorem"]; 
 

 
Array.prototype.intersect = function intersect(a, ...b) { 
 
    const c = function (a, b) { 
 
     b = new Set(b); 
 
     return a.filter((a) => b.has(a)); 
 
    }; 
 
    return undefined === a ? this : intersect.call(c(this, a), ...b); 
 
}; 
 

 
console.log(array1.intersect(array2, array3, array4)); 
 
// ["Lorem"]

Các vấn đề liên quan