2012-11-10 40 views
5

Vì vậy, sau khi tìm kiếm interwebz trong một vài giờ tôi đã không tìm thấy giải pháp mà tôi đang tìm kiếm.Liên minh mảng đối tượng trong JavaScript?

Tôi có hai mảng chứa đối tượng trò chơi có nhiều thông tin bên trong. (ví dụ: tiêu đề, sên, hình thu nhỏ, tóm tắt, thể loại, ngày phát hành ...).

Mảng 1 là tập hợp các đối tượng phù hợp với sở thích của người dùng được chỉ định trong quá trình đăng ký.

Mảng 2 là tập hợp các đối tượng khớp với các trò chơi đã mua của những người dùng tương tự. (Những người dùng tương tự là những người có cùng sở thích chung)

Bài toán: Có thể xảy ra, trong trường hợp của tôi, có hai trò chơi giống nhau - trò chơi trong Mảng 1 cũng nằm trong Mảng 2. mảng trò chơi là có bởi vì nó phù hợp với sở thích của người dùng. Trong mảng thứ hai trò chơi là có bởi vì một người dùng tương tự đã mua trò chơi đó.

Câu hỏi: Underscore.js có một liên kết hàm nhỏ() http://underscorejs.org/#union cung cấp cho bạn kết hợp hai mảng, nhưng nó không hoạt động với một mảng đối tượng, chỉ trên các giá trị nguyên thủy. Làm thế nào tôi có thể làm cho nó làm việc cho tôi một sự kết hợp của mảng các đối tượng?

+0

Vì vậy, những gì bạn cần là một kết hợp sâu sắc và mở rộng? https://gist.github.com/1868955 http://stackoverflow.com/questions/7549574/merge-js-objects-without-overwriting http://stackoverflow.com/questions/896043/how-can-i- merge-2-javascript-objects-populating-the-properties-in-one-if-them-d – jcolebrand

+0

http://phrogz.net/JS/ArraySetMath.js – Phrogz

+1

Tôi biết đây không phải là câu hỏi của bạn, nhưng có bạn xem xét việc sử dụng các gameIds duy nhất và sử dụng đối tượng khóa: giá trị cho các bộ sưu tập của bạn? – cbayram

Trả lời

14

Bạn có thể tự triển khai khá dễ dàng. Trong trường hợp này, chúng ta làm cho hàm tổng quát, để nó có thể lấy các mảng của bất kỳ kiểu dữ liệu nào và kết hợp chúng bằng cách sử dụng hàm so sánh được cung cấp.

// arr1 and arr2 are arrays of any length; equalityFunc is a function which 
// can compare two items and return true if they're equal and false otherwise 
function arrayUnion(arr1, arr2, equalityFunc) { 
    var union = arr1.concat(arr2); 

    for (var i = 0; i < union.length; i++) { 
     for (var j = i+1; j < union.length; j++) { 
      if (equalityFunc(union[i], union[j])) { 
       union.splice(j, 1); 
       j--; 
      } 
     } 
    } 

    return union; 
} 

function areGamesEqual(g1, g2) { 
    return g1.title === g2.title; 
} 

// Function call example 
arrayUnion(arr1, arr2, areGamesEqual); 

Tham khảo Object comparison in JavaScript để triển khai so sánh đối tượng khác nhau.

+0

Đánh tôi với nó. Thực hiện tốt đẹp. – L0j1k

+0

Hmm không may mắn làm cho nó hoạt động. Trả về không xác định. https://gist.github.com/4049901 –

+0

Vâng, điều đó không ngạc nhiên khi tôi quên 'return' một giá trị. :) Chỉnh sửa. –

1

jQuery có phương pháp extend:

$.extend(true, object1, object2); 
+0

Vì vậy, hiện underscore.js, nhưng tôi đã tìm kiếm một hoạt động công đoàn. Mở rộng từ những gì tôi hiểu là để hợp nhất hai đối tượng. Tôi muốn loại bỏ một đối tượng hoàn toàn nếu nó đã có trong mảng. Tôi đoán bạn có thể sử dụng extend(), nó không phải là thứ đầu tiên xuất hiện trong đầu tôi. –

2

Sử dụng gạch mở rộng, bạn có thể làm:

var objects = [{ bar : 1, nuts : 2} , {foo : 3, nuts : 4}] 
_.extend.apply(this,objects) 

Nếu danh sách có thể để trống, hãy chắc chắn để thêm một đối tượng rỗng với nó.

4

Bạn có thể làm điều đó bằng cách gạch dưới:

// collectionUnion(*arrays, iteratee) 
function collectionUnion() { 
    var args = Array.prototype.slice.call(arguments); 
    var it = args.pop(); 

    return _.uniq(_.flatten(args, true), it); 
} 

Nó chỉ là một improvment của hàm gốc _.union(*arrays), thêm một iteratee làm việc sưu tập (mảng các đối tượng).

đây làm thế nào để sử dụng nó:

var result = collectionUnion(a, b, c, function (item) { 
    return item.id; 
}); 

Chức năng ban đầu mà chỉ đang làm việc với mảng, trông giống như rằng:

_.union = function() { 
    return _.uniq(flatten(arguments, true, true)); 
}; 

Và trong tiền thưởng một ví dụ đầy đủ:

// collectionUnion(*arrays, iteratee) 
function collectionUnion() { 
    var args = Array.prototype.slice.call(arguments); 
    var it = args.pop(); 

    return _.uniq(_.flatten(args, true), it); 
} 

var a = [{id: 0}, {id: 1}, {id: 2}]; 
var b = [{id: 2}, {id: 3}]; 
var c = [{id: 0}, {id: 1}, {id: 2}]; 

var result = collectionUnion(a, b, c, function (item) { 
    return item.id; 
}); 

console.log(result); // [ { id: 0 }, { id: 1 }, { id: 2 }, { id: 3 } ] 
+0

Trong bộ sưu tập công đoàn (tiền thưởng cuối cùng một ví dụ đầy đủ) tôi sẽ sử dụng: '_.uniqBy (_. Flatten (args, true), 'prop-id')' https://lodash.com/docs/4.17.4 #uniqBy – Crisboot

1

Set (ES6/ES2015) sẽ giúp bạn.

const info1 = {id: 1} 
 
const info2 = {id: 2} 
 
const info3 = {id: 3} 
 

 
const array1 = [info1, info2] 
 
const array2 = [info1, info3] 
 

 
const union = [...new Set([...array1, ...array2])] 
 

 
console.log(union)

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