简体   繁体   中英

compare two arrays of objects and sort based on one array of objects and push when doesn't match

I have two arrays in javascript

array1 = [{id: 4, value:'xyz'}, {id: 2, value:'pqr'}, {id: 5, value:'abc'}]
array2 = [
         [{id: 5, value:'abc'}, {id: 4, value:'xyz'}],
         [{id: 5, value:'abc'}, {id: 2, value:'pqr'}],
         [{id: 4, value:'xyz'}, {id: 2, value:'pqr'}],
         [{id: 2, value:'pqr'}, {id: 5, value:'abc'}]
]

array2 is array of array of objects, all these arrays inside array 2 should be first of all sorted as per the array1 sequence and then object with null should be pushed if that particular id doesn't exist at that particular index.

output = [
         [{id: 4, value:'xyz'}, {id: null, value:null}, {id: 5, value:'abc'}],
         [{id: null, value:null}, {id: 2, value:'pqr'}, {id: 5, value:'abc'}],
         [{id: 4, value:'xyz'}, {id: 2, value:'pqr'}, {id: null, value:null}],
         [{id: 4, value:'xyz'}, {id: 2, value:'pqr'}, {id: null, value:null}],
         [{id: null, value:null}, {id: 2, value:'pqr'}, {id: 5, value:'abc'}]
].

Here is my code

export const mapOrder = (array, order, key) => {
    let arr = [];
    array.sort((a, b) => {
        let A = a[key];
        let B = b[key];
        if (order.indexOf(A) > order.indexOf(B)) {
            return 1;
        }
        return -1;
    });
    if (order.length > 0) {
        for (let i = 0; i < order.length; i++) {
            for (let j = 0; j < array.length; j++) {
                if (order[i] === array[j].UserId) {
                    arr.push(array[j]);
                } else {
                    arr.push({ id: null, value: null})
                }
            }
        }
        array = arr;
    }
    return arr;
};

First you can loop over the second array and save the ID's to a new Set, Then loop over the first array and if the current item's ID is present in the set then return the current object or return the object with id and value as null`

 const array1 = [{id: 4, value:'xyz'}, {id: 2, value:'pqr'}, {id: 5, value:'abc'}] const array2 = [{id: 5, value:'abc'}, {id: 4, value:'xyz'}] function test(arr1, arr2) { const set = new Set() arr2.forEach(i => set.add(i.id)) return arr1.map((i) => set.has(i.id)? i: { id: null, value: null }) } console.log(test(array1,array2))

You could make a Map from your array2, where each id from the objects in array2 point to an array of objects with that particular id value. Then you can use .flatMap() on array1 and get all the objects for the id of the currently iterated object by using .get() on your map. If .get() returns nothing, you can provide the default object (where id and value are null ):

 const array1 = [{id: 4, value:'xyz'}, {id: 2, value:'pqr'}, {id: 5, value:'abc'}]; const array2 = [{id: 5, value:'abc'}, {id: 4, value:'xyz'}]; // group the arrays into a Map const grouped = array2.reduce((map, obj) => map.set(obj.id, (map.get(obj.id) || []).concat(obj)), new Map ); const res = array1.flatMap(({id}) => grouped.get(id) || ({id: null, value: null})); console.log(res);

You might be able to remove the .flatMap() and the need to array of objects in your Map if objects in array2 have unique id values (ie: an object with the same idea cannot exist). If this can be the case, you can simplify the above:

 const array1 = [{id: 4, value:'xyz'}, {id: 2, value:'pqr'}, {id: 5, value:'abc'}]; const array2 = [{id: 5, value:'abc'}, {id: 4, value:'xyz'}]; const ids = new Map(array2.map((obj) => [obj.id, obj])); const res = array1.map(({id}) => ids.get(id) || ({id: null, value: null})); console.log(res);

You could collect the object in an object first and them map the collected objects or take a placeholder.

 var array1 = [{ id: 4, value: 'xyz' }, { id: 2, value: 'pqr' }, { id: 5, value: 'abc' }], array2 = [{ id: 5, value: 'abc' }, { id: 4, value: 'xyz' }], result = array1.map( (o => ({ id }) => o[id] || { id: null, value: null }) (array2.reduce((r, o) => ({...r, [o.id]: o }), {})) ); console.log(result);
 .as-console-wrapper { max-height: 100%;important: top; 0; }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM