2016-07-27 20 views
15

Tôi có hai mảng với một trường chung thành viên. làm thế nào tôi có thể hợp nhất chủ đề một cách dễ dàng?Làm cách nào để hợp nhất hai mảng đối tượng bằng cách sử dụng lodash?

Ví dụ:

var arr1 = [{ 
    "member" : ObjectId("57989cbe54cf5d2ce83ff9d6"), 
    "bank" : ObjectId("575b052ca6f66a5732749ecc"), 
    "country" : ObjectId("575b0523a6f66a5732749ecb") 
}, 
{ 
    "member" : ObjectId("57989cbe54cf5d2ce83ff9d8"), 
    "bank" : ObjectId("575b052ca6f66a5732749ecc"), 
    "country" : ObjectId("575b0523a6f66a5732749ecb") 
}]; 

var arr2 = [{ 
    "member" : ObjectId("57989cbe54cf5d2ce83ff9d6"), 
    "name" : 'xxxxxx', 
    "age" : 25 
}, 
{ 
    "member" : ObjectId("57989cbe54cf5d2ce83ff9d8"), 
    "name" : 'yyyyyyyyyy', 
    "age" : 26 
}]; 

dự kiến:

var merge = [{ 
    "member" : ObjectId("57989cbe54cf5d2ce83ff9d6"), 
    "bank" : ObjectId("575b052ca6f66a5732749ecc"), 
    "country" : ObjectId("575b0523a6f66a5732749ecb"), 
    "name" : 'xxxxxx', 
    "age" : 25 
}, 
{ 
    "member" : ObjectId("57989cbe54cf5d2ce83ff9d8"), 
    "bank" : ObjectId("575b052ca6f66a5732749ecc"), 
    "country" : ObjectId("575b0523a6f66a5732749ecb"), 
    "name" : 'yyyyyyyyyy', 
    "age" : 26 
}]; 

tôi đã cố gắng

var merge = _.unionBy(arr1, arr2, 'member'); 

nhưng không sáp nhập như exp ected. được hiển thị mảng1 giá trị. Ai giúp tôi với?

+1

http://youmightnotneedjquery.com/#deep_extend hoặc http://youmightnotneedjquery.com/#extend, mà liên kết đến https: //lodash.com/docs#assign –

+1

Tôi nhớ rằng bạn đã hỏi [câu hỏi trước đây] (http://stackoverflow.com/questions/38505448/how-to-merge-multiple-array-of-object-by -id-in-javascript) và tôi nghĩ rằng câu trả lời được upvoted nhất nên đã sufficed như là câu trả lời. Chỉ cần thay đổi 'memberID' bằng' member' và xóa 'arr3' và' arr4' trong phần nối. – ryeballar

+0

Câu trả lời bạn nhận được trước đây là nhiều hơn một viên ngọc quý hơn bạn nhận ra. Đừng yêu cầu chúng tôi đăng nó hai lần, chỉ cần đóng một bản sao. – 4castle

Trả lời

23

Nếu cả hai mảng đều đúng thứ tự; trong đó mỗi mục tương ứng với số nhận dạng thành viên liên quan của nó thì bạn chỉ có thể sử dụng.

var merge = _.merge(arr1, arr2); 

Đó là phiên bản ngắn:

var merge = _.chain(arr1).zip(arr2).map(function(item) { 
    return _.merge.apply(null, item); 
}).value(); 

Hoặc, nếu các dữ liệu trong các mảng không có trong bất kỳ thứ tự cụ thể, bạn có thể tìm kiếm các mục liên quan đến bằng giá trị thành viên.

var merge = _.map(arr1, function(item) { 
    return _.merge(item, _.find(arr2, { 'member' : item.member })); 
}); 

Bạn có thể dễ dàng chuyển đổi điều này thành bản mixin. Xem ví dụ dưới đây:

_.mixin({ 
 
    'mergeByKey' : function(arr1, arr2, key) { 
 
    var criteria = {}; 
 
    criteria[key] = null; 
 
    return _.map(arr1, function(item) { 
 
     criteria[key] = item[key]; 
 
     return _.merge(item, _.find(arr2, criteria)); 
 
    }); 
 
    } 
 
}); 
 

 
var arr1 = [{ 
 
    "member": 'ObjectId("57989cbe54cf5d2ce83ff9d6")', 
 
    "bank": 'ObjectId("575b052ca6f66a5732749ecc")', 
 
    "country": 'ObjectId("575b0523a6f66a5732749ecb")' 
 
}, { 
 
    "member": 'ObjectId("57989cbe54cf5d2ce83ff9d8")', 
 
    "bank": 'ObjectId("575b052ca6f66a5732749ecc")', 
 
    "country": 'ObjectId("575b0523a6f66a5732749ecb")' 
 
}]; 
 

 
var arr2 = [{ 
 
    "member": 'ObjectId("57989cbe54cf5d2ce83ff9d8")', 
 
    "name": 'yyyyyyyyyy', 
 
    "age": 26 
 
}, { 
 
    "member": 'ObjectId("57989cbe54cf5d2ce83ff9d6")', 
 
    "name": 'xxxxxx', 
 
    "age": 25 
 
}]; 
 

 
var arr3 = _.mergeByKey(arr1, arr2, 'member'); 
 

 
document.body.innerHTML = JSON.stringify(arr3, null, 4);
body { font-family: monospace; white-space: pre; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.0/lodash.min.js"></script>

+2

Sử dụng '_.find' bên trong' _.map' đang tạo giải pháp O (n^2). – 4castle

+1

Cũng lưu ý rằng câu trả lời này sẽ bỏ qua các phần tử trong arr2 không tồn tại trong arr1. Thích câu trả lời của Ori Drori. – joniba

+0

không hoạt động chút nào, tôi kết thúc với giá trị của mảng cuối thay vì cả mảng được hợp nhất – phil1234

14

Tạo từ điển cho cả hai mảng sử dụng _.keyBy(), merge các từ điển, và chuyển đổi kết quả để một mảng với _.values(). Theo cách này, thứ tự của các mảng không quan trọng. Ngoài ra, nó cũng có thể xử lý các mảng có độ dài khác nhau.

const ObjectId = (id) => id; // mock of ObjectId 
 
const arr1 = [{"member" : ObjectId("57989cbe54cf5d2ce83ff9d8"),"bank" : ObjectId("575b052ca6f66a5732749ecc"),"country" : ObjectId("575b0523a6f66a5732749ecb")},{"member" : ObjectId("57989cbe54cf5d2ce83ff9d6"),"bank" : ObjectId("575b052ca6f66a5732749ecc"),"country" : ObjectId("575b0523a6f66a5732749ecb")}]; 
 
const arr2 = [{"member" : ObjectId("57989cbe54cf5d2ce83ff9d6"),"name" : 'xxxxxx',"age" : 25},{"member" : ObjectId("57989cbe54cf5d2ce83ff9d8"),"name" : 'yyyyyyyyyy',"age" : 26}]; 
 

 
const merged = _(arr1) // start sequence 
 
    .keyBy('member') // create a dictionary of the 1st array 
 
    .merge(_.keyBy(arr2, 'member')) // create a dictionary of the 2nd array, and merge it to the 1st 
 
    .values() // turn the combined dictionary to array 
 
    .value(); // get the value (array) out of the sequence 
 

 
console.log(merged);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.0/lodash.min.js"></script>

Sử dụng ES6 Map

concat các mảng, và reduce mảng kết hợp với một bản đồ. Sử dụng Object#assign để kết hợp các đối tượng với cùng một member đối tượng mới và lưu trữ trên bản đồ. Chuyển đổi bản đồ để một mảng với Map#valuesspread:

const ObjectId = (id) => id; // mock of ObjectId 
 
const arr1 = [{"member" : ObjectId("57989cbe54cf5d2ce83ff9d8"),"bank" : ObjectId("575b052ca6f66a5732749ecc"),"country" : ObjectId("575b0523a6f66a5732749ecb")},{"member" : ObjectId("57989cbe54cf5d2ce83ff9d6"),"bank" : ObjectId("575b052ca6f66a5732749ecc"),"country" : ObjectId("575b0523a6f66a5732749ecb")}]; 
 
const arr2 = [{"member" : ObjectId("57989cbe54cf5d2ce83ff9d6"),"name" : 'xxxxxx',"age" : 25},{"member" : ObjectId("57989cbe54cf5d2ce83ff9d8"),"name" : 'yyyyyyyyyy',"age" : 26}]; 
 

 
const merged = [...arr1.concat(arr2).reduce((m, o) => 
 
    m.set(o.member, Object.assign(m.get(o.member) || {}, o)) 
 
, new Map()).values()]; 
 

 
console.log(merged);

+1

Tôi thích cái này – Seeker

+0

yep cái này hoạt động trong khi lodash thất bại thảm hại và chỉ trả lại nội dung của mảng cuối – phil1234

+0

@ phil1234 - xin hãy giải thích. Cả hai giải pháp của tôi (với lodash và không có) làm cùng một thứ, và có cùng một kết quả - kết hợp các thuộc tính của các đối tượng trong hai mảng có id thành viên tương tự. –

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