【问题标题】:How to get the difference between two arrays of objects in JavaScript如何在 JavaScript 中获取两个对象数组之间的差异
【发布时间】:2014-03-26 02:59:04
【问题描述】:

我有两个这样的结果集:

// Result 1
[
    { value: "0", display: "Jamsheer" },
    { value: "1", display: "Muhammed" },
    { value: "2", display: "Ravi" },
    { value: "3", display: "Ajmal" },
    { value: "4", display: "Ryan" }
]

// Result 2
[
    { value: "0", display: "Jamsheer" },
    { value: "1", display: "Muhammed" },
    { value: "2", display: "Ravi" },
    { value: "3", display: "Ajmal" },
]

我需要的最终结果是这些数组之间的差异——最终结果应该是这样的:

[{ value: "4", display: "Ryan" }]

在 JavaScript 中可以做这样的事情吗?

【问题讨论】:

  • 那么,您想要一个包含 both 数组中未出现的所有元素的数组,按值过滤并显示?
  • 我想要两个数组的区别。该值将出现在任何一个数组中。
  • 它看起来像登录到萤火虫控制台时显示的数组...
  • 对不起,json对象错了……你需要改=for:

标签: javascript arrays object


【解决方案1】:

只使用原生 JS,这样的事情就可以了:

const a = [{ value:"4a55eff3-1e0d-4a81-9105-3ddd7521d642", 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"}];
const b = [{ value:"4a55eff3-1e0d-4a81-9105-3ddd7521d642", 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"}];

// A comparer used to determine if two entries are equal.
const isSameUser = (a, b) => a.value == b.value && a.display == b.display;

// Get items that only occur in the left array,
// using the compareFunction to determine equality.
const onlyInLeft = (left, right, compareFunction) => 
  left.filter(leftValue =>
    !right.some(rightValue => 
      compareFunction(leftValue, rightValue)));

const onlyInA = onlyInLeft(a, b, isSameUser);
const onlyInB = onlyInLeft(b, a, isSameUser);

const result = [...onlyInA, ...onlyInB];

console.log(result);

【讨论】:

  • 这行得通,也许是最好的直接答案,但最好将它变成接受谓词和两个列表并通过适当应用谓词返回两个列表的对称差异的东西. (如果它比必须运行所有 m * n 比较两次更有效,则加分!)
  • @Cerbrus:是的。谓词是一个返回布尔值(truefalse 值)的函数。在这种情况下,如果我们通过要求用户通过相等性检查,将相等性测试的概念从其余代码中分离出来一个函数,我们可以做一个简单的通用算法。
  • @ScottSauyet:我花了一段时间才再次找到这个答案,但现在好多了:D
  • 该比较器为当前数组中的每个项目运行内部函数。 otherArray.filterotherArray 返回与当前项目相同的项目数组。如果有任何此类项目 (.length > 0),则当前项目在两个数组之间不是唯一的,因此不应从 comparer@Whymess 返回当前项目。
  • 我喜欢这个答案,非常棒,谢谢
【解决方案2】:

对于那些喜欢 ES6 中的单行解决方案的人,可以这样:

const arrayOne = [ 
  { value: "4a55eff3-1e0d-4a81-9105-3ddd7521d642", 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" },
];
          
const arrayTwo = [
  { value: "4a55eff3-1e0d-4a81-9105-3ddd7521d642", 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"},
];

const results = arrayOne.filter(({ value: id1 }) => !arrayTwo.some(({ value: id2 }) => id2 === id1));

console.log(results);

【讨论】:

  • 请解释一下!
  • 我喜欢这个解决方案。它创建了一个只有 value 属性的临时对象,所以保持小
  • 我喜欢这个解决方案,就像一个魅力!谢谢!!
  • 完美运行,谢谢!!
  • 好的,谢谢!!
【解决方案3】:

您可以将Array.prototype.filter()Array.prototype.some() 结合使用。

这是一个示例(假设您的数组存储在变量result1result2 中):

//Find values that are in result1 but not in result2
var uniqueResultOne = result1.filter(function(obj) {
    return !result2.some(function(obj2) {
        return obj.value == obj2.value;
    });
});

//Find values that are in result2 but not in result1
var uniqueResultTwo = result2.filter(function(obj) {
    return !result1.some(function(obj2) {
        return obj.value == obj2.value;
    });
});

//Combine the two arrays of unique entries
var result = uniqueResultOne.concat(uniqueResultTwo);

【讨论】:

    【解决方案4】:
    import differenceBy from 'lodash/differenceBy'
    
    const myDifferences = differenceBy(Result1, Result2, 'value')
    

    这将返回两个对象数组之间的差异,使用键 value 来比较它们。注意两个具有相同值的东西不会被返回,因为其他键被忽略了。

    这是lodash的一部分。

    【讨论】:

    • 上面的json对象是错误的。当尝试这种方式时 change = for :
    • 要安装它,你需要把它写成小写:npm i lodash.differenceby。好消息是differenceBy(Result1, Result2, 'value')differenceBy(Result2, Result1, 'value') 不同,因此您可以使用一个查看已删除的内容,而使用另一个查看已添加的内容。非常有用。
    【解决方案5】:

    我采用了一种更通用的方法,尽管在想法上与 @Cerbrus@Kasper Moerch 的方法相似。我创建了一个函数,它接受一个谓词来确定两个对象是否相等(这里我们忽略了$$hashKey 属性,但它可以是任何东西)并返回一个函数,该函数根据该谓词计算两个列表的对称差:

    a = [{ value:"4a55eff3-1e0d-4a81-9105-3ddd7521d642", 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-3ddd7521d642", 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"}]
    
    var makeSymmDiffFunc = (function() {
        var contains = function(pred, a, list) {
            var idx = -1, len = list.length;
            while (++idx < len) {if (pred(a, list[idx])) {return true;}}
            return false;
        };
        var complement = function(pred, a, b) {
            return a.filter(function(elem) {return !contains(pred, elem, b);});
        };
        return function(pred) {
            return function(a, b) {
                return complement(pred, a, b).concat(complement(pred, b, a));
            };
        };
    }());
    
    var myDiff = makeSymmDiffFunc(function(x, y) {
        return x.value === y.value && x.display === y.display;
    });
    
    var result = myDiff(a, b); //=>  {value="a63a6f77-c637-454e-abf2-dfb9b543af6c", display="Ryan"}
    

    与 Cerebrus 的方法相比(就像 Kasper Moerch 的方法一样),它有一个小优势,即它可以提前逃脱;如果它找到匹配项,它就不会检查列表的其余部分。如果我有一个方便的curry 函数,我会做一些不同的事情,但这很好用。

    说明

    评论要求对初学者进行更详细的解释。这是一个尝试。

    我们将以下函数传递给makeSymmDiffFunc

    function(x, y) {
        return x.value === y.value && x.display === y.display;
    }
    

    这个函数是我们判断两个对象相等的方式。像所有返回truefalse 的函数一样,它可以称为“谓词函数”,但这只是术语。重点是makeSymmDiffFunc 配置了一个函数,该函数接受两个对象,如果我们认为它们相等则返回true,如果不相等则返回false

    使用它,makeSymmDiffFunc(阅读“使对称差分函数”)返回给我们一个新函数:

            return function(a, b) {
                return complement(pred, a, b).concat(complement(pred, b, a));
            };
    

    这是我们将实际使用的函数。我们将两个列表传递给它,它会找到第一个中的元素而不是第二个中的元素,然后是第二个中的元素而不是第一个中的元素,然后将这两个列表组合起来。

    不过,再看一遍,我绝对可以从您的代码中得到启发,并通过使用 some 简化了 main 函数:

    var makeSymmDiffFunc = (function() {
        var complement = function(pred, a, b) {
            return a.filter(function(x) {
                return !b.some(function(y) {return pred(x, y);});
            });
        };
        return function(pred) {
            return function(a, b) {
                return complement(pred, a, b).concat(complement(pred, b, a));
            };
        };
    }());
    

    complement 使用谓词并返回其第一个列表中的元素,而不是第二个列表中的元素。这比我第一次使用单独的contains 函数更简单。

    最后,将 main 函数包装在一个立即调用的函数表达式 (IIFE) 中,以将内部 complement 函数保持在全局范围之外。


    几年后更新

    既然 ES2015 已经非常普及,我建议使用相同的技术,但样板要少得多:

    const diffBy = (pred) => (a, b) => a.filter(x => !b.some(y => pred(x, y)))
    const makeSymmDiffFunc = (pred) => (a, b) => diffBy(pred)(a, b).concat(diffBy(pred)(b, a))
    
    const myDiff = makeSymmDiffFunc((x, y) => x.value === y.value && x.display === y.display)
    
    const result = myDiff(a, b)
    //=>  {value="a63a6f77-c637-454e-abf2-dfb9b543af6c", display="Ryan"}
    

    【讨论】:

    • 您能否为您的代码添加更多解释?我不确定 JavaScript 的初学者是否会理解谓词方法的工作原理。
    • @KasperMoerch:添加了一个冗长的解释。我希望这会有所帮助。 (这也让我认识到这段代码应该进行认真的清理。)
    【解决方案6】:

    另外,说两个不同key value的对象数组

    // Array Object 1
    const arrayObjOne = [
        { userId: "1", display: "Jamsheer" },
        { userId: "2", display: "Muhammed" },
        { userId: "3", display: "Ravi" },
        { userId: "4", display: "Ajmal" },
        { userId: "5", display: "Ryan" }
    ]
    
    // Array Object 2
    const arrayObjTwo =[
        { empId: "1", display: "Jamsheer", designation:"Jr. Officer" },
        { empId: "2", display: "Muhammed", designation:"Jr. Officer" },
        { empId: "3", display: "Ravi", designation:"Sr. Officer" },
        { empId: "4", display: "Ajmal", designation:"Ast. Manager" },
    ]
    

    您可以在es5native js 中使用filter 来减去两个数组对象。

    //Find data that are in arrayObjOne but not in arrayObjTwo
    var uniqueResultArrayObjOne = arrayObjOne.filter(function(objOne) {
        return !arrayObjTwo.some(function(objTwo) {
            return objOne.userId == objTwo.empId;
        });
    });
    

    ES6 中,您可以将箭头函数与Object destructuringES6 一起使用。

    const ResultArrayObjOne = arrayObjOne.filter(({ userId: userId }) => !arrayObjTwo.some(({ empId: empId }) => empId === userId));
    
    console.log(ResultArrayObjOne);
    

    【讨论】:

    • 你救了我兄弟! ES6 代码 sn-ps 效果更好。谢谢!
    【解决方案7】:

    您可以使用键作为数组中每个对象对应的唯一值创建一个对象,然后根据其他对象中键的存在情况过滤每个数组。它降低了操作的复杂性。

    ES6

    let a = [{ value:"4a55eff3-1e0d-4a81-9105-3ddd7521d642", 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"}];
    let b = [{ value:"4a55eff3-1e0d-4a81-9105-3ddd7521d642", 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"}];
    
    let valuesA = a.reduce((a,{value}) => Object.assign(a, {[value]:value}), {});
    let valuesB = b.reduce((a,{value}) => Object.assign(a, {[value]:value}), {});
    let result = [...a.filter(({value}) => !valuesB[value]), ...b.filter(({value}) => !valuesA[value])];
    console.log(result);

    ES5

    var a = [{ value:"4a55eff3-1e0d-4a81-9105-3ddd7521d642", 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"}];
    var b = [{ value:"4a55eff3-1e0d-4a81-9105-3ddd7521d642", 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"}];
    
    var valuesA = a.reduce(function(a,c){a[c.value] = c.value; return a; }, {});
    var valuesB = b.reduce(function(a,c){a[c.value] = c.value; return a; }, {});
    var result = a.filter(function(c){ return !valuesB[c.value]}).concat(b.filter(function(c){ return !valuesA[c.value]}));
    console.log(result);

    【讨论】:

      【解决方案8】:

      我认为@Cerbrus 解决方案是正确的。我已经实现了相同的解决方案,但将重复的代码提取到它自己的函数(DRY)中。

       function filterByDifference(array1, array2, compareField) {
        var onlyInA = differenceInFirstArray(array1, array2, compareField);
        var onlyInb = differenceInFirstArray(array2, array1, compareField);
        return onlyInA.concat(onlyInb);
      }
      
      function differenceInFirstArray(array1, array2, compareField) {
        return array1.filter(function (current) {
          return array2.filter(function (current_b) {
              return current_b[compareField] === current[compareField];
            }).length == 0;
        });
      }
      

      【讨论】:

        【解决方案9】:

        我使用过滤器和一些方法找到了这个解决方案。

        resultFilter = (firstArray, secondArray) => {
          return firstArray.filter(firstArrayItem =>
            !secondArray.some(
              secondArrayItem => firstArrayItem._user === secondArrayItem._user
            )
          );
        };

        【讨论】:

          【解决方案10】:

          你可以在 b 上做 diff a,在 a 上做 diff b,然后合并两个结果

          let a = [
              { value: "0", display: "Jamsheer" },
              { value: "1", display: "Muhammed" },
              { value: "2", display: "Ravi" },
              { value: "3", display: "Ajmal" },
              { value: "4", display: "Ryan" }
          ]
          
          let b = [
              { value: "0", display: "Jamsheer" },
              { value: "1", display: "Muhammed" },
              { value: "2", display: "Ravi" },
              { value: "3", display: "Ajmal" }
          ]
          
          // b diff a
          let resultA = b.filter(elm => !a.map(elm => JSON.stringify(elm)).includes(JSON.stringify(elm)));
          
          // a diff b
          let resultB = a.filter(elm => !b.map(elm => JSON.stringify(elm)).includes(JSON.stringify(elm)));  
          
          // show merge 
          console.log([...resultA, ...resultB]);

          【讨论】:

            【解决方案11】:

            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);

            【讨论】:

              【解决方案12】:

              这里的大多数答案都相当复杂,但是这背后的逻辑不是很简单吗?

              1. 检查哪个数组更长,并将其作为第一个参数提供(如果长度相等,则参数顺序无关紧要)
              2. 遍历array1。
              3. 对于 array1 的当前迭代元素,检查它是否存在于 array2 中
              4. 如果不存在,则比
              5. 将其推送到“差异”数组
              const getArraysDifference = (longerArray, array2) => {
                const difference = [];
              
                longerArray.forEach(el1 => {      /*1*/
                  el1IsPresentInArr2 = array2.some(el2 => el2.value === el1.value); /*2*/
              
                  if (!el1IsPresentInArr2) { /*3*/
                    difference.push(el1);    /*4*/
                  }
                });
              
                return difference;
              }
              

              O(n^2) 复杂度。

              【讨论】:

              • 复杂性加 1
              【解决方案13】:

              当涉及到大数组时,我更喜欢 map 对象。

              // create tow arrays
              array1 = Array.from({length: 400},() => ({value:Math.floor(Math.random() * 4000)}))
              array2 = Array.from({length: 400},() => ({value:Math.floor(Math.random() * 4000)}))
              
              // calc diff with some function
              console.time('diff with some');
              results = array2.filter(({ value: id1 }) => array1.some(({ value: id2 }) => id2 === id1));
              console.log('diff results ',results.length)
              console.timeEnd('diff with some');
              
              // calc diff with map object
              console.time('diff with map');
              array1Map = {};
              for(const item1 of array1){
                  array1Map[item1.value] = true;
              }
              results = array2.filter(({ value: id2 }) => array1Map[id2]);
              console.log('map results ',results.length)
              console.timeEnd('diff with map');

              【讨论】:

                【解决方案14】:

                我制作了一个比较任何类型的 2 个对象并且可以运行修改处理程序的通用差异 gist.github.com/bortunac "diff.js" 使用的前任:

                old_obj={a:1,b:2,c:[1,2]}
                now_obj={a:2 , c:[1,3,5],d:55}
                

                所以属性a被修改,b被删除,c被修改,d被添加

                var handler=function(type,pointer){
                console.log(type,pointer,this.old.point(pointer)," | ",this.now.point(pointer)); 
                

                }

                现在使用喜欢

                df=new diff();
                df.analize(now_obj,old_obj);
                df.react(handler);
                

                控制台会显示

                mdf ["a"]  1 | 2 
                mdf ["c", "1"]  2 | 3 
                add ["c", "2"]  undefined | 5 
                add ["d"]  undefined | 55 
                del ["b"]  2 | undefined 
                

                【讨论】:

                  【解决方案15】:

                  最通用和最简单的方法:

                  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;
                  }
                  

                  【讨论】:

                    【解决方案16】:

                    JavaScript 有 Maps,它提供 O(1) 的插入和查找时间。因此,这可以在 O(n) 中解决(而不是像所有其他答案那样在 O(n²) 中解决)。为此,有必要为每个对象生成一个唯一的原始(字符串/数字)键。可以JSON.stringify,但这很容易出错,因为元素的顺序会影响相等性:

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

                    因此,我会采用一个没有出现在任何值中的分隔符并手动组成一个字符串:

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

                    然后创建一个地图。当一个元素已经存在于 Map 中时,它会被移除,否则它会被添加。因此,仅包含奇数次(仅表示一次)的元素仍然存在。这只有在每个数组中的元素都是唯一的情况下才有效:

                    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);

                    【讨论】:

                      【解决方案17】:

                      我在寻找一种方法来挑选一个数组中与另一个数组中的任何值都不匹配的第一项并设法最终使用 array.find() 和 array.filter 对其进行排序时遇到了这个问题() 像这样

                      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
                      

                      如果您需要在交叉检查下一个最佳选项之前继续获取更新的列表,这应该足够好:)

                      【讨论】:

                        【解决方案18】:

                        最简单的方法是同时使用 filtersome 请参考以下链接 DifferenceInTwoArrayOfObjectInSimpleWay

                        【讨论】:

                          【解决方案19】:

                          大多数观察到的代码不会检查整个对象,而只会比较特定方法的值。这个解决方案是一样的,只是你可以自己指定那个方法。

                          这是一个例子:

                          const arr1 = [
                             {
                                id: 1,
                                name: "Tom",
                                scores: {
                                   math: 80,
                                   science: 100
                                }
                             },
                             {
                                id: 2,
                                name: "John",
                                scores: {
                                   math: 50,
                                   science: 70
                                }
                             }
                          ];
                          const arr2 = [
                             {
                                id: 1,
                                name: "Tom",
                                scores: {
                                   math: 80,
                                   science: 70
                                }
                             }
                          ];
                          
                          function getDifference(array1, array2, attr) {
                            return array1.filter(object1 => {
                              return !array2.some(object2 => {
                                return eval("object1." + attr + " == object2." + attr);
                              });
                            });
                          }
                          
                          // ?️ [{id: 2, name: 'John'...
                          console.log(getDifference(arr1, arr2, "id"));
                          
                          // ?️ [{id: 2, name: 'John'...
                          console.log(getDifference(arr1, arr2, "scores.math"));
                          
                          // ?️ [{id: 1, name: 'Tom'...
                          console.log(getDifference(arr1, arr2, "scores.science"));
                          

                          【讨论】:

                            【解决方案20】:

                            如果你愿意使用外部库,你可以使用 underscore.js 中的 _.difference 来实现。 _.difference 从数组中返回其他数组中不存在的值。

                            _.difference([1,2,3,4,5][1,4,10])
                            
                            ==>[2,3,5]
                            

                            【讨论】:

                            • 这仅适用于具有原始值的数组。如果数组包含对象列表,就像这个问题所问的那样,它将无法工作,因为它会尝试比较引用而不是对象本身,这几乎总是意味着一切都不同。
                            • 感谢罗斯让我免于头痛。我正要报告一个要下划线的错误。
                            猜你喜欢
                            • 2010-11-14
                            • 1970-01-01
                            相关资源
                            最近更新 更多