Hợp nhất 2 mảng đối tượng


112

Hãy xem một ví dụ.

var arr1 = new Array({name: "lang", value: "English"}, {name: "age", value: "18"});
var arr2 = new Array({name : "childs", value: '5'}, {name: "lang", value: "German"});

Tôi cần hợp nhất 2 mảng đối tượng đó và tạo mảng sau:

arr3 = new Array({name: "lang", value: "German"}, {name: "age", value: "18"}, {name : "childs", value: '5'});

Có JavaScript hoặc hàm jQuery nào để làm điều này không?

$.extendkhông hợp với tôi. Nó trở lại

arr4 = new Array({name : "childs", value: '5'}, {name: "lang", value: "German"});

15
Điều gì đã xảy ra với {name: "lang", value: "English"}?
Shadow Wizard là Ear For You

Lấy làm tiếc. Tôi đề cập đến $ .extend, không phải $ .merge.
Alexander

1
Ý tôi là, logic liên quan là gì? Bạn muốn hợp nhất các mảng như thế nào? Nó không rõ ràng từ các ví dụ của bạn.
Shadow Wizard là Ear For You

Cảm ơn tất cả các bạn rất nhiều. Tôi đã làm điều đó theo cách thủ công.
Alexander

6
@ShadowWizard, tôi nghĩ ý của OP là cập nhật nếu tồn tại và đẩy nếu không.
Amin Mohamed Ajani

Câu trả lời:


84

Nếu bạn muốn gộp 2 mảng đối tượng trong JavaScript. Bạn có thể sử dụng thủ thuật một dòng này

Array.prototype.push.apply(arr1,arr2);

Ví dụ

var arr1 = [{name: "lang", value: "English"},{name: "age", value: "18"}];
var arr2 = [{name : "childs", value: '5'}, {name: "lang", value: "German"}];

Array.prototype.push.apply(arr1,arr2); 

console.log(arr1);  // final merged result will be in arr1

Đầu ra:

[{"name":"lang","value":"English"},
{"name":"age","value":"18"},
{"name":"childs","value":"5"},
{"name":"lang","value":"German"}]

Đây là cách sử dụng đơn giản nhất cho đến nay và hoạt động tốt. Cảm ơn vì đã chia sẻ nó.
Leo Caseiro

17
cùng kết quả là đơn giản hơn nhiều:arr1 = arr1.concat(arr2)
keithpjolley

7
nhưng đây không phải là hợp nhất!
Dimitri Kopriwa

1
Kết quả không giống nhau. concatsẽ trả về một mảng mới và phá vỡ bất kỳ tham chiếu nào bạn có.
Bpainter

8
Điều này không trả lời câu hỏi, mảng kết quả phải có 3 đối tượng, không phải 4. Bạn đã thay đổi các giá trị mẫu. Về cơ bản những gì OP muốn là hợp nhất hai mảng đối tượng và loại bỏ các giá trị trùng lặp.
Ranjan

43

Với ES6, bạn có thể làm điều đó rất dễ dàng như sau:

var arr1 = new Array({name: "lang", value: "German"}, {name: "age", value: "18"});
var arr2 = new Array({name : "childs", value: '5'}, {name: "lang", value: "German"});
var arr3 = [...arr1, ...arr2];

Đầu ra:

    arr3 = [
      {"name":"lang","value":"German"},
      {"name":"age","value":"18"},
      {"name":"childs","value":"5"},
      {"name":"lang","value":"German"}
    ]

6
Đây phải là câu trả lời hàng đầu.
nocdib

20
Điều này không làm những gì OP đang tìm kiếm, không nên có vật thể thứ hai chứa{ name: 'lang', value: 'German'}
Sẽ

3
Tôi không biết lý do tại sao câu trả lời này được bình chọn. Điều mà @ daveanderson88 muốn là câu trả lời này khác.
Nguyễn Xuân Hoàng

33

Đối với những người đang thử nghiệm những thứ hiện đại:

var odd = [
    { name : "1", arr: "in odd" },
    { name : "3", arr: "in odd" }
];

var even = [
    { name : "1", arr: "in even" },
    { name : "2", arr: "in even" },
    { name : "4", arr: "in even" }
];

// ----
// ES5 using Array.filter and Array.find
function merge(a, b, prop){
  var reduced = a.filter(function(aitem){
      return ! b.find(function(bitem){
          return aitem[prop] === bitem[prop];
      });
  });
  return reduced.concat(b);
}
console.log( "ES5", merge(odd, even, "name") );

// ----
// ES6 arrow functions
function merge(a, b, prop){
    var reduced =  a.filter( aitem => ! b.find ( bitem => aitem[prop] === bitem[prop]) )
  return reduced.concat(b);
}
console.log( "ES6", merge(odd, even, "name") );

// ----
// ES6 one-liner
var merge = (a, b, p) => a.filter( aa => ! b.find ( bb => aa[p] === bb[p]) ).concat(b);


console.log( "ES6 one-liner", merge(odd, even, "name") );

// Results
// ( stuff in the "b" array replaces things in the "a" array )
// [
//    {
//         "name": "3",
//         "arr": "in odd"
//     },
//     {
//         "name": "1",
//         "arr": "in even"
//     },
//     {
//         "name": "2",
//         "arr": "in even"
//     },
//     {
//         "name": "4",
//         "arr": "in even"
//     }
// ]

29

Cập nhật ngày 12 tháng 10 năm 2019

Phiên bản mới chỉ dựa trên Javascript mới hơn và không cần bất kỳ thư viện bên thứ ba nào.

const mergeByProperty = (target, source, prop) => {
  source.forEach(sourceElement => {
    let targetElement = target.find(targetElement => {
      return sourceElement[prop] === targetElement[prop];
    })
    targetElement ? Object.assign(targetElement, sourceElement) : target.push(sourceElement);
  })
}
var target /* arr1 */ = [{name: "lang", value: "English"}, {name: "age", value: "18"}];
var source /* arr2 */ = [{name : "childs", value: '5'}, {name: "lang", value: "German"}];

mergeByProperty(target, source, 'name');

console.log(target)

Câu trả lời này đã trở nên cũ kỹ, những dấu gạch ngang như lodash và gạch dưới ngày nay ít cần thiết hơn nhiều. Trong phiên bản mới này, mảng đích (arr1) là mảng mà chúng tôi đang làm việc và muốn cập nhật. Các nguồn (arr2) mảng là nơi mà các dữ liệu mới đang đến từ, và chúng tôi muốn nó sáp nhập vào của chúng tôi mục tiêu mảng.

Chúng tôi lặp lại mảng nguồn để tìm kiếm dữ liệu mới và đối với mọi đối tượng chưa được tìm thấy trong mảng đích của chúng tôi, chúng tôi chỉ cần thêm đối tượng đó bằng target.push (sourceElement) Nếu, dựa trên thuộc tính khóa của chúng tôi ('name') , an đối tượng đã có trong mảng đích của chúng tôi - chúng tôi cập nhật các thuộc tính và giá trị của nó bằng cách sử dụng Object.assign (targetElement, sourceElement) . “Mục tiêu” của chúng tôi sẽ luôn là cùng một mảng và có nội dung cập nhật.


Câu trả lời cũ sử dụng dấu gạch dưới hoặc dấu gạch ngang

Tôi luôn đến đây từ google và tôi luôn không hài lòng từ các câu trả lời. Câu trả lời YOU là tốt nhưng sẽ dễ dàng và gọn gàng hơn khi sử dụng underscore.js

DEMO: http://jsfiddle.net/guya/eAWKR/

Đây là một hàm tổng quát hơn sẽ hợp nhất 2 mảng bằng cách sử dụng thuộc tính của các đối tượng của chúng. Trong trường hợp này tài sản là 'tên'

var arr1 = [{name: "lang", value: "English"}, {name: "age", value: "18"}];
var arr2 = [{name : "childs", value: '5'}, {name: "lang", value: "German"}];

function mergeByProperty(arr1, arr2, prop) {
  _.each(arr2, function(arr2obj) {
    var arr1obj = _.find(arr1, function(arr1obj) {
      return arr1obj[prop] === arr2obj[prop];
    });

    arr1obj ? _.extend(arr1obj, arr2obj) : arr1.push(arr2obj);
  });
}

mergeByProperty(arr1, arr2, 'name');

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

[{name: "lang", value: "German"}, {name: "age", value: "18"}, {name : "childs", value: '5'}]

6
Gần giống ở LOC, độ phức tạp như câu trả lời của @ YOU, ngoại trừ điều này chậm hơn nhiều (phần lớn là do các lệnh gọi hàm bổ sung và thực tế câu trả lời của YOU khai thác thủ thuật mảng liên kết JS để tìm các mục với O (1) tra cứu). Điều này bên cạnh thực tế là bạn cần phải mang theo một thư viện bổ sung.
Mrchief

Bạn sẽ không nhận được bất kỳ sự khác biệt nào về hiệu suất trừ khi bạn đang xử lý các trường hợp cực kỳ phức tạp. Về lib bổ sung - gạch dưới, lodash và tương tự thường đã được sử dụng và có những lợi ích khác, dù sao thì người ta cũng nên cân nhắc sử dụng nó. Hầu hết các nhà phát triển và ứng dụng sẽ được hưởng lợi từ sự đơn giản và tổng quát của giải pháp này.
guya

1
@guya Tôi nhận ra cái này đã cũ nhưng gạch dưới, lodash và các thứ tương tự nói chung đều đã được sử dụng và có những lợi ích khác trong khi như bạn nói chúng có những lợi ích khác, đó là một giả định rất lớn khi nói rằng chúng thường đã được sử dụng.
Craicerjack

26
var arr3 = [];
for(var i in arr1){
   var shared = false;
   for (var j in arr2)
       if (arr2[j].name == arr1[i].name) {
           shared = true;
           break;
       }
   if(!shared) arr3.push(arr1[i])
}
arr3 = arr3.concat(arr2);

nhập mô tả hình ảnh ở đây


1
Câu trả lời này có độ phức tạp về thời gian không tốt (O (n ^ 2)). Giải pháp O (n) có thể sử dụng bản đồ băm.
Alex von Brandenfels vào

19

Rất đơn giản bằng cách sử dụng toán tử spread ES6:

const array1 = [{a: 'HI!'}, {b: 'HOW'}]
const array2 = [{c: 'ARE'}, {d: 'YOU?'}]

const mergedArray = [ ...array1, ...array2 ]
console.log('Merged Array: ', mergedArray)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

Merged Array: [ {a: 'HI!'}, {b: 'HOW'} {c: 'ARE'}, {d: 'YOU?'} ]

Lưu ý: Giải pháp trên là chỉ hợp nhất hai mảng bằng cách sử dụng toán tử trải phổ ES6.

Chỉnh sửa vào ngày 07 tháng 1 năm 2020 bởi @ bh4r4th: Do bối cảnh đã thay đổi do các chỉnh sửa sau giải pháp ban đầu của tôi. Tôi muốn cập nhật giải pháp của mình để phù hợp với tiêu chí hiện tại. I E,

  1. Hợp nhất các đối tượng mảng mà không tạo các đối tượng trùng lặp và

  2. cập nhật valuenếu thuộc nametính đã tồn tại trong mảng trước

const arr1 = [
    { name: "lang", value: "English" },
    { name: "age", value: "18" }
]
const arr2 = [
    { name: "childs", value: '2' }, 
    { name: "lang", value: "German" }
]
const arr3 = [
    { name: "lang", value: "German" },
    { name: "age", value: "28" },
    { name: "childs", value: '5' }
]

// Convert to key value dictionary or object
const convertToKeyValueDict = arrayObj => {
    const val = {}
    arrayObj.forEach(ob => {
        val[ob.name] = ob.value
    })
    return val
}

// update or merge array
const updateOrMerge = (a1, a2) => {
    const ob1 = convertToKeyValueDict(a1)
    const ob2 = convertToKeyValueDict(a2)
    // Note: Spread operator with objects used here
    const merged_obj = {...ob1, ...ob2}
    const val = Object.entries(merged_obj)
    return val.map(obj => ({ name: obj[0], value: obj[1] }))
}

const v1 = updateOrMerge(arr1, arr2)
const v2 = updateOrMerge(v1, arr3)
console.log(`Merged array1 and array2: ${JSON.stringify(v1)} \n\n`)
console.log(`Merged above response and array3: ${JSON.stringify(v2)} \n\n`)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>


1
Đây sẽ là câu trả lời được chấp nhận vào năm 2019! Tôi sẽ đề xuất giải pháp tương tự sau khi xem các câu trả lời khác có số phiếu bầu cao hơn! @Alexander Rất dễ bỏ sót nhưng hãy chấp nhận điều này!
iaforek

Sai. Người hỏi đặc biệt muốn THAY THẾ các đối tượng nếu chúng có thuộc tính trùng lặp, không chỉ đơn giản là nối chúng.
HaveSpacesuit

Cảm ơn bạn đã chỉ ra @HaveSpacesuit. Tôi đã trả lời câu hỏi này vào năm 2018 khi bối cảnh là chỉ hợp nhất hai mảng. Sẽ sớm chỉnh sửa câu trả lời này để sử dụng setkhi hợp nhất để loại bỏ các bản sao. Điều này sẽ tạo đối số biến mới nhưng mã tối thiểu. Tuy nhiên, tôi không phải là một fan hâm mộ lớn của tải trọng có tên được xác định là thuộc tính và giá trị dưới dạng các loại khác nhau. Thay vào đó tôi thích hơn [ { lang: &#39;German&#39;, age: 25}] . Bằng cách này, trọng lượng tải trọng sẽ được giảm thiểu trong khi giao tiếp giữa các dịch vụ.
bh4r4th

Hiện tôi đã cập nhật giải pháp để phù hợp với ngữ cảnh đã thay đổi của câu hỏi.
bh4r4

16

Hợp nhất hai mảng:

var arr1 = new Array({name: "lang", value: "English"}, {name: "age", value: "18"});
var arr2 = new Array({name : "childs", value: '5'}, {name: "lang", value: "German"});
var result=arr1.concat(arr2);
// result: [{name: "lang", value: "English"}, {name: "age", value: "18"}, {name : "childs", value: '5'}, {name: "lang", value: "German"}]

Hợp nhất hai mảng không có giá trị trùng lặp cho 'name':

var arr1 = new Array({name: "lang", value: "English"}, {name: "age", value: "18"});
var arr2 = new Array({name : "childs", value: '5'}, {name: "lang", value: "German"});
var i,p,obj={},result=[];
for(i=0;i<arr1.length;i++)obj[arr1[i].name]=arr1[i].value;
for(i=0;i<arr2.length;i++)obj[arr2[i].name]=arr2[i].value;
for(p in obj)if(obj.hasOwnProperty(p))result.push({name:p,value:obj[p]});
// result: [{name: "lang", value: "German"}, {name: "age", value: "18"}, {name : "childs", value: '5'}]

Array.concat là cách thích hợp để hợp nhất 2 mảng thành một. Tôi cũng thích giả định mở rộng rằng khái niệm hợp nhất "đúng" đã được giải quyết (dựa trên một khóa nhất định của mỗi phần tử mảng).
bob

14

Cách dễ nhất là với một số phép thuật của ES6:

Hợp nhất hai với các bản sao:

const a = [{a: 1}, {b: 2}]
const b = [{a: 1}]

const result = a.concat(b) // [{a: 1}, {b: 2}, {a: 1}]

Không có bản sao nó giống như ở trên cộng:

const distinct = [...new Set(result.map(item => item.YOUR_PROP_HERE))]


1
concat không làm việc với các hạng mục bản chất khác nhau
fdsfdsfdsfds

7

Với lodash:

_.uniqBy([...arr1, ...arr2], 'name')

cú pháp ES6 đó hoạt động với 2 mảng, không phải với 2 mảng đối tượng.
Dario

7

Đây là cách tôi đã giải quyết một vấn đề tương tự trong bối cảnh ES6:

function merge(array1, array2, prop) {
    return array2.map(function (item2) {
        var item1 = array1.find(function (item1) {
            return item1[prop] === item2[prop];
        });
        return Object.assign({}, item1, item2);
    });
}

Lưu ý: Cách tiếp cận này sẽ không trả về bất kỳ mục nào từ array1 không xuất hiện trong array2.


CHỈNH SỬA: Tôi có một số tình huống mà tôi muốn giữ lại các mục không xuất hiện trong mảng thứ hai nên tôi đã nghĩ ra một phương pháp khác.

function mergeArrays(arrays, prop) {
    const merged = {};

    arrays.forEach(arr => {
        arr.forEach(item => {
            merged[item[prop]] = Object.assign({}, merged[item[prop]], item);
        });
    });

    return Object.values(merged);
}

var arr1 = [
    { name: 'Bob', age: 11 },
    { name: 'Ben', age: 12 },
    { name: 'Bill', age: 13 },
];

var arr2 = [
    { name: 'Bob', age: 22 },
    { name: 'Fred', age: 24 },
    { name: 'Jack', age: 25 },
    { name: 'Ben' },
];

console.log(mergeArrays([arr1, arr2], 'name'));

6

Tuy nhiên, một phiên bản khác sử dụng reduce() method:

var arr1 = new Array({name: "lang", value: "English"}, {name: "age", value: "18"});
var arr2 = new Array({name : "childs", value: '5'}, {name: "lang", value: "German"});

var arr = arr1.concat(arr2).reduce(function(prev, current, index, array){ 
   
   if(!(current.name in prev.keys)) {
      prev.keys[current.name] = index;
      prev.result.push(current);   
   } 
   else{
       prev.result[prev.keys[current.name]] = current;
   }  

   return prev;
},{result: [], keys: {}}).result;
  
document.getElementById("output").innerHTML = JSON.stringify(arr,null,2);    
<pre id="output"/>


Nó hiệu quả tuyệt vời đối với tôi. Một vấn đề nhỏ mặc dù là đặt hàng đôi khi là kỳ quặc khi sáp nhập 3 đối tượng json lớn
crh225

5

Giải pháp đơn giản

var tx = [{"id":1},{"id":2}];
var tx1 = [{"id":3},{"id":4}];


var txHistory = tx.concat(tx1)

console.log(txHistory); 
// output
 // [{"id":1},{"id":2},{"id":3},{"id":4}];

4

Bạn có thể sử dụng một đối tượng để thu thập các thuộc tính của mình trong khi thay thế các bản sao và sau đó mở rộng / san phẳng đối tượng đó trở lại một mảng. Một cái gì đó như thế này:

function merge(args) {
    args  = Array.prototype.slice.call(arguments);
    var o = { };
    for(var i = 0; i < args.length; ++i)
        for(var j = 0; j < args[i].length; ++j)
            o[args[i][j].name] = args[i][j].value;
    return o;
}

function expand(o) {
    var a = [ ];
    for(var p in o)
        if(o.hasOwnProperty(p))
            a.push({ name: p, value: o[p]});
    return a;
}

var arr1 = new Array({name: "lang", value: "English"}, {name: "age", value: "18"});
var arr2 = new Array({name : "childs", value: '5'}, {name: "lang", value: "German"});
var arr3 = expand(merge(arr1, arr2));

Tôi không biết đây có phải là cách nhanh nhất không nhưng nó hoạt động với bất kỳ số lượng mảng đầu vào nào; ví dụ, điều này:

var a = expand(
    merge(
        [{name: "lang", value: "English"}, {name: "age", value: "18"}],
        [{name: "childs", value: '5'}, {name: "lang", value: "German"}],
        [{name: 'lang', value: 'Pancakes'}]
    )
);

Cung cấp cho bạn điều tương tự trong ađó arr3với "tiếng Đức" được thay thế bằng "Bánh kếp".

Tất nhiên, cách tiếp cận này giả định rằng tất cả các đối tượng của bạn đều có cùng một {name: ..., value: ...}dạng.

Bạn có thể thấy nó hoạt động ở đây (vui lòng mở bảng điều khiển của bạn): http://jsfiddle.net/ambiguous/UtBbB/


2

Điều gì về jQuery Merge?

http://api.jquery.com/jQuery.merge/

Ví dụ về jsFiddle tại đây: http://jsfiddle.net/ygByD/


Điều đó sẽ không thay thế tiếng Anh bằng tiếng Đức như đã chỉ định, quá trình hợp nhất đang diễn ra dọc theo các namethuộc tính.
mu quá ngắn

À vâng, bạn nói đúng! Tôi không nhìn thấy đặc điểm kỹ thuật đó trong nháy mắt!
321X

+1. Tốt! mặt khác, nó là một chức năng khá tốt để hợp nhất các mảng javascript của các đối tượng
Muhammad Raheel

2

Tôi đang gặp phải vấn đề tương tự và dựa trên câu trả lời của guya, tôi đã mở rộng thư viện gạch dưới và cũng bổ sung thêm một chút chức năng mà tôi đang yêu cầu. Đây là Gist .

/**
 * Merges two object-like arrays based on a key property and also merges its array-like attributes specified in objectPropertiesToMerge.
 * It also removes falsy values after merging object properties.
 *
 * @param firstArray The original object-like array.
 * @param secondArray An object-like array to add to the firstArray.
 * @param keyProperty The object property that will be used to check if objects from different arrays are the same or not.
 * @param objectPropertiesToMerge The list of object properties that you want to merge. It all must be arrays.
 * @returns The updated original array.
 */
function merge(firstArray, secondArray, keyProperty, objectPropertiesToMerge) {

    function mergeObjectProperties(object, otherObject, objectPropertiesToMerge) {
        _.each(objectPropertiesToMerge, function (eachProperty) {
            object[eachProperty] = _.chain(object[eachProperty]).union(otherObject[eachProperty]).compact().value();
        });
    }

    if (firstArray.length === 0) {
        _.each(secondArray, function (each) {
            firstArray.push(each);
        });
    } else {
        _.each(secondArray, function (itemFromSecond) {
            var itemFromFirst = _.find(firstArray, function (item) {
                return item[keyProperty] === itemFromSecond[keyProperty];
            });

            if (itemFromFirst) {
                mergeObjectProperties(itemFromFirst, itemFromSecond, objectPropertiesToMerge);
            } else {
                firstArray.push(itemFromSecond);
            }
    });
    }

    return firstArray;
}

_.mixin({
            merge: merge
        });

Hy vọng nó sẽ hữu ích! Trân trọng!


2

Gần đây tôi đã bị bối rối với vấn đề này và tôi đến đây với hy vọng có câu trả lời nhưng câu trả lời được chấp nhận sử dụng 2 vòng lặp for in mà tôi không thích. Cuối cùng thì tôi cũng làm được cái của riêng mình. Không phụ thuộc vào bất kỳ thư viện nào:

function find(objArr, keyToFind){
    var foundPos = objArr.map(function(ob){
        return ob.type;
    }).indexOf(keyToFind);
    return foundPos;
}

function update(arr1,arr2){
    for(var i = 0, len = arr2.length, current; i< len; i++){
        var pos = find(arr1, arr2[i].name); 
        current = arr2[i];
        if(pos !== -1) for(var key in arr2) arr1[pos][key] = arr2[key];
        else arr1[arr1.length] = current;
    } 
}

Điều này cũng duy trì thứ tự của arr1.


2

bạn có thể sử dụng chức năng sau

const merge = (a, b, key = "id") =>
  a.filter(elem => !b.find(subElem => subElem[key] === elem[key]))
   .concat(b);

và cố gắng

merge(arr1, arr2, 'name');

Nhờ cách Diago với tính năng bất biến ES6 `` `export const mergeArrays = (a1, a2, key =" id ") => a1 && a2! = Null? [... a1.filter (a =>! a2.find (p => p [key] === a [key])), ... a2]: null; ``
Musa

1

Ở đây, đầu tiên tôi lọc arr1dựa trên phần tử có trong arr2hay không. Nếu nó hiện diện thì không thêm nó vào mảng kết quả, nếu không hãy thêm. Và sau đó tôi thêm arr2vào kết quả.

arr1.filter(item => {
  if (!arr2.some(item1=>item.name==item1.name)) {
    return item
  }
}).concat(arr2)

Vui lòng cung cấp lời giải thích cho câu trả lời của bạn. Vì vậy, nếu bất kỳ người nào khác đọc câu hỏi và câu trả lời thì có thể dễ dàng hiểu được.
Mittal Patel

Mặc dù câu trả lời này có thể đúng và hữu ích, nhưng sẽ được ưu tiên hơn nếu bạn bao gồm một số lời giải thích cùng với nó để giải thích cách nó giúp giải quyết vấn đề. Điều này trở nên đặc biệt hữu ích trong tương lai, nếu có một thay đổi (có thể không liên quan) khiến nó ngừng hoạt động và người dùng cần hiểu nó đã từng hoạt động như thế nào.
Erty Seidohl

Cảm ơn các bạn. Tôi đã cập nhật mô tả giải pháp. Nếu nó có vẻ pls đúng upvote :)
maulik Bhatt

0

Ngoài đỉnh đầu của tôi - hãy thử mở rộng jquery

var arr3 = jQuery.extend(arr1,arr2....)

Lấy làm tiếc. Chính xác thì hàm này trả về arr4. Không phải $ .merge. Cái cuối cùng cũng không phù hợp với tôi, vì nó trùng lặp các đối tượng.
Alexander

0

var newArray = yourArray.concat(otherArray); console.log('Concatenated newArray: ', newArray);


tôi đồng ý rằng điều này có ý nghĩa hơn nhiều so với Array.protype.push.apply()câu trả lời, nhưng, nó không thực hiện hợp nhất như OP muốn.
keithpjolley

bạn không thể nhận được kết quả phía trên bằng cách sử dụng 'concat' nếu bạn có hai mảng đối tượng hợp nhất. Vui lòng kiểm tra điều này trên jsfiddle.net/jahanzaibaslam/z22n5tuo
Jahanzaib Aslam

0

Dựa trên câu trả lời của @ YOU nhưng vẫn giữ thứ tự:

var arr3 = [];
for(var i in arr1){
   var shared = false;
   for (var j in arr2)
       if (arr2[j].name == arr1[i].name) {
           arr3.push(arr1[j]
           shared = true;
           break;
       }
   if(!shared) arr3.push(arr1[i])
}

for(var j in arr2){
   var shared = false;
   for (var i in arr1)
       if (arr2[j].name == arr1[i].name) {
           shared = true;
           break;
       }
   if(!shared) arr3.push(arr2[j])
}
arr3

Tôi biết giải pháp này kém hiệu quả hơn, nhưng nó cần thiết nếu bạn muốn giữ trật tự và vẫn cập nhật các đối tượng.


0

Đây là một plugin jQuery mà tôi đã viết để hợp nhất hai mảng đối tượng bằng một khóa. Hãy nhớ rằng điều này sửa đổi mảng đích tại chỗ.

(function($) {
  $.extendObjectArray = function(destArray, srcArray, key) {
    for (var index = 0; index < srcArray.length; index++) {
      var srcObject = srcArray[index];
      var existObject = destArray.filter(function(destObj) {
        return destObj[key] === srcObject[key];
      });
      if (existObject.length > 0) {
        var existingIndex = destArray.indexOf(existObject[0]);
        $.extend(true, destArray[existingIndex], srcObject);
      } else {
        destArray.push(srcObject);
      }
    }
    return destArray;
  };
})(jQuery);

var arr1 = [
  { name: "lang",   value: "English" },
  { name: "age",    value: "18"      }
];
var arr2 = [
  { name: "childs", value: '5'       },
  { name: "lang",   value: "German"  }
];
var arr3 = $.extendObjectArray(arr1, arr2, 'name');

console.log(JSON.stringify(arr3, null, 2));
.as-console-wrapper { top: 0; max-height: 100% !important; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


Phiên bản ES6

(function($) {
  $.extendObjectArray = (destArr, srcArr, key) => {
    srcArr.forEach(srcObj => (existObj => {
      if (existObj.length) {
        $.extend(true, destArr[destArr.indexOf(existObj[0])], srcObj);
      } else {
        destArr.push(srcObj);
      }
    })(destArr.filter(v => v[key] === srcObj[key])));
    return destArr;
  };
})(jQuery);

0

Sử dụng lodash bạn muốn _.uniqBy

var arr3 = _.uniqBy(arr1.concat(arr2), 'name'); // es5

let arr3 = _.uniqBy([...arr1, ...arr2], 'name'); // es6

Thứ tự của arr1, arr2 vấn đề!

Xem tài liệu https://lodash.com/docs/4.17.4#uniqBy


cần sử dụng bên thứ ba?
Nguyễn Xuân Hoàng

không, nhưng đó là cách ngắn gọn nhất để đạt được điều đó, và không chỉ bất kỳ bên thứ ba nào, là trụ sở của nó!
danday74

0
const extend = function*(ls,xs){
   yield* ls;
   yield* xs;
}

console.log( [...extend([1,2,3],[4,5,6])]  );

2
Chỉ cần không cung cấp câu trả lời của câu hỏi. Cũng giải thích cách giải pháp này giải quyết vấn đề.
Mittal Patel

0
merge(a, b, key) {
    let merged = [];
    a.forEach(aitem => {
        let found = b.find( bitem => aitem[key] === bitem[key]);
        merged.push(found? found: aitem);
    });
    return merged;
}

0

Nếu bạn muốn hợp nhất 2 mảng, nhưng loại bỏ các đối tượng trùng lặp, hãy sử dụng điều này. Các bản sao được xác định trên .uniqueIdmỗi đối tượng

function mergeObjectArraysRemovingDuplicates(firstObjectArray, secondObjectArray) {
  return firstObjectArray.concat(
    secondObjectArray.filter((object) => !firstObjectArray.map((x) => x.uniqueId).includes(object.uniqueId)),
  );
}

0

Thử cái này:

var a = [{"a":20, "b":10,"c":"c","d":"asd","f":"any"}]
var b = [{"a":20, "b":10,"c":"c", "e":"nan","g":10200}]

var p = []
_.map(a, function(da){
var chk = _.filter(b, function(ds){
return da.a ===ds.a
})[0]
p.push(_.extend(da, chk))


})

console.log(p)

OutPut sẽ là:

  [{
    "a": 20,
    "b": 10,
    "c": "c",
    "d": "asd",
    "f": "any",
    "e": "nan",
    "g": 10200
  }]

0
const arr1 = ["Vijendra","Singh"];
const arr2 = ["Singh", "Shakya"];

arr2.forEach(item => {
        if(!arr1.find(k => k===item))
          arr1.push(item)
    });


console.log(arr1)

0

Giải pháp sử dụng Bản đồ JS:

const merge = (arr1, arr2, prop) => {
    const resultMap = new Map([...arr1.map((item) => [item[prop], item])]);
    arr2.forEach((item) => {
        const mapItem = resultMap.get(item[prop]);
        if (mapItem) Object.assign(mapItem, item);
        else resultMap.set(item[prop], item);
    });
    return [...resultMap.values()];
};

const arr1 = new Array({name: "lang", value: "English"}, {name: "age", value: "18"});
const arr2 = new Array({name : "childs", value: '5'}, {name: "lang", value: "German"});

console.log(merge(arr1, arr2, "name"));

Sản xuất:

kết quả của hàm merge ()


0
const array1 = [{id:1,name:'ganza'},
{id:2,name:'respice dddd'},{id:4,name:'respice dddd'},{id:6,name:'respice dddd'},
{id:7,name:'respice dddd'}];
const array2 = [{id:1,name:'ganza respice'},{id:2,name:'respice'},{id:3,name:'mg'}];

 function mergeTwoArray(array1,array2){

    return array1.map((item,i)=>{
        if(array2[i] && item.id===array2[i].id){
          return array2[i];
          }else{
            return item;
          }
    });
  }

const result = merge(array1,array2);
console.log(result);
//here is the result:  Array [Object { id: 1, name: "ganza respice" }, Object { id: 2, name: "respice" }, Object { id: 4, name: "respice dddd" }, Object { id: 6, name: "respice dddd" }, Object { id: 7, name: "respice dddd" }]
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.