How to get the difference between two arrays of objects in JavaScript

前端 未结 18 1058
没有蜡笔的小新
没有蜡笔的小新 2020-11-22 04:45

I have two result sets like this:

// Result 1
[
    { value: \"0\", display: \"Jamsheer\" },
    { value: \"1\", display: \"Muhammed\" },
    { value: \"2\",         


        
相关标签:
18条回答
  • 2020-11-22 05:14

    I came across this question while searching for a way to pick out the first item in one array that does not match any of the values in another array and managed to sort it out eventually with array.find() and array.filter() like this

    var carList= ['mercedes', 'lamborghini', 'bmw', 'honda', 'chrysler'];
    var declinedOptions = ['mercedes', 'lamborghini'];
    
    const nextOption = carList.find(car=>{
        const duplicate = declinedOptions.filter(declined=> {
          return declined === car
        })
        console.log('duplicate:',duplicate) //should list out each declined option
        if(duplicate.length === 0){//if theres no duplicate, thats the nextOption
          return car
        }
    })
    
    console.log('nextOption:', nextOption);
    //expected outputs
    //duplicate: mercedes
    //duplicate: lamborghini
    //duplicate: []
    //nextOption: bmw
    

    if you need to keep fetching an updated list before cross-checking for the next best option this should work well enough :)

    0 讨论(0)
  • 2020-11-22 05:15

    JavaScript has Maps, that provide O(1) insertion and lookup time. Therefore this can be solved in O(n) (and not O(n²) as all the other answers do). For that, it is necessary to generate a unique primitive (string / number) key for each object. One could JSON.stringify, but that's quite error prone as the order of elements could influence equality:

     JSON.stringify({ a: 1, b: 2 }) !== JSON.stringify({ b: 2, a: 1 })
    

    Therefore, I'd take a delimiter that does not appear in any of the values and compose a string manually:

    const toHash = value => value.value + "@" + value.display;
    

    Then a Map gets created. When an element exists already in the Map, it gets removed, otherwise it gets added. Therefore only the elements that are included odd times (meaning only once) remain. This will only work if the elements are unique in each array:

    const entries = new Map();
    
    for(const el of [...firstArray, ...secondArray]) {
      const key = toHash(el);
      if(entries.has(key)) {
        entries.delete(key);
      } else {
        entries.set(key, el);
      }
    }
    
    const result = [...entries.values()];
    

    const firstArray = [
        { value: "0", display: "Jamsheer" },
        { value: "1", display: "Muhammed" },
        { value: "2", display: "Ravi" },
        { value: "3", display: "Ajmal" },
        { value: "4", display: "Ryan" }
    ]
    
    const secondArray = [
        { value: "0", display: "Jamsheer" },
        { value: "1", display: "Muhammed" },
        { value: "2", display: "Ravi" },
        { value: "3", display: "Ajmal" },
    ];
    
    const toHash = value => value.value + "@" + value.display;
    
    const entries = new Map();
    
    for(const el of [...firstArray, ...secondArray]) {
      const key = toHash(el);
      if(entries.has(key)) {
        entries.delete(key);
      } else {
        entries.set(key, el);
      }
    }
      
    const result = [...entries.values()];
    
    console.log(result);

    0 讨论(0)
  • 2020-11-22 05:17

    Most generic and simple way:

    findObject(listOfObjects, objectToSearch) {
        let found = false, matchingKeys = 0;
        for(let object of listOfObjects) {
            found = false;
            matchingKeys = 0;
            for(let key of Object.keys(object)) {
                if(object[key]==objectToSearch[key]) matchingKeys++;
            }
            if(matchingKeys==Object.keys(object).length) {
                found = true;
                break;
            }
        }
        return found;
    }
    
    get_removed_list_of_objects(old_array, new_array) {
        // console.log('old:',old_array);
        // console.log('new:',new_array);
        let foundList = [];
        for(let object of old_array) {
            if(!this.findObject(new_array, object)) foundList.push(object);
        }
        return foundList;
    }
    
    get_added_list_of_objects(old_array, new_array) {
        let foundList = [];
        for(let object of new_array) {
            if(!this.findObject(old_array, object)) foundList.push(object);
        }
        return foundList;
    }
    
    0 讨论(0)
  • 2020-11-22 05:18

    let obj1 =[
                     { id: 1, submenu_name: 'login' },
                     { id: 2, submenu_name: 'Profile',}, 
                     { id: 3, submenu_name: 'password',  },  
                     { id: 4, submenu_name: 'reset',}
                   ] ;
     let obj2 =[
                     { id: 2}, 
                     { id: 3 },
                   ] ;
                   
    // Need Similar obj 
    const result1 = obj1.filter(function(o1){
     return obj2.some(function(o2){
        return o1.id == o2.id;          // id is unnique both array object
      });
    });
     console.log(result1);
    
    
    
    // Need differnt obj 
     const result2 = obj1.filter(function(o1){
     return !obj2.some(function(o2){    //  for diffrent we use NOT (!) befor obj2 here
        return o1.id == o2.id;          // id is unnique both array object
      });
    });
     console.log(result2);

    0 讨论(0)
  • 2020-11-22 05:19
    import differenceBy from 'lodash/differenceBy'
    
    const myDifferences = differenceBy(Result1, Result2, 'value')
    

    This will return the difference between two arrays of objects, using the key value to compare them. Note two things with the same value will not be returned, as the other keys are ignored.

    This is a part of lodash.

    0 讨论(0)
  • 2020-11-22 05:20

    Using only native JS, something like this will work:

    a = [{ value:"4a55eff3-1e0d-4a81-9105-3ffffd7521d642", display:"Jamsheer"}, { value:"644838b3-604d-4899-8b78-09e4799f586f", display:"Muhammed"}, { value:"b6ee537a-375c-45bd-b9d4-4dd84a75041d", display:"Ravi"}, { value:"e97339e1-939d-47ab-974c-1b68c9cfb536", display:"Ajmal"},  { value:"a63a6f77-c637-454e-abf2-dfb9b543af6c", display:"Ryan"}]
    b = [{ value:"4a55eff3-1e0d-4a81-9105-3ffffd7521d642", display:"Jamsheer", $$hashKey:"008"}, { value:"644838b3-604d-4899-8b78-09e4799f586f", display:"Muhammed", $$hashKey:"009"}, { value:"b6ee537a-375c-45bd-b9d4-4dd84a75041d", display:"Ravi", $$hashKey:"00A"}, { value:"e97339e1-939d-47ab-974c-1b68c9cfb536", display:"Ajmal", $$hashKey:"00B"}]
    
    function comparer(otherArray){
      return function(current){
        return otherArray.filter(function(other){
          return other.value == current.value && other.display == current.display
        }).length == 0;
      }
    }
    
    var onlyInA = a.filter(comparer(b));
    var onlyInB = b.filter(comparer(a));
    
    result = onlyInA.concat(onlyInB);
    
    console.log(result);

    0 讨论(0)
提交回复
热议问题