Search code examples
javascriptarrayslodash

Lodash/Javascript Compare array or objects, fail if any props match


Preferably using Lodash, how can I compare two array of objects, and if any of the properties match, return false, while excluding 'name'.

array1 = [
  {
    "name": "componentA",
    "img": "www.url.com/image1.jpg"
  },
  {
    "name": "componentB",
    "header": "this is the default header",
    "text": "here is a default text post",
    "buttons": [{
      "title": "a button",
      "url": "http://www.url.com"
    }]
  },
  {
    "name": "componentB",
    "header": "this is the default header 2",
    "text": "here is a default text post 2 ",
    "buttons": [
      {
        "title": "a button 2",
        "url": "http://www.url2.com"
      },
      {
        "title": "a second button 2",
        "url": "http://www.url2_1.com"
      }
    ]
  }
]

vs

array2 = [
  {
    "name": "componentA",
    "img": "www.url.com/imageA.jpg"
  },
  {
    "name": "componentB",
    "header": "header changed",
    "text": "text post changed",
    "buttons": [{
      "title": "button changed",
      "url": "http://www.website.com"
    }]
  },
  {
    "name": "componentB",
    "header": "header 2 changed",
    "text": "here is a default text post 2 ",
    "buttons": [
      {
        "title": "button 2 changed",
        "url": "http://www.website2.com"
      },
      {
        "title": "button 2 changed again",
        "url": "http://www.website2_1.com"
      }
    ]
  },
]

As you can see every property has changed except in array2[2].text, which would result in error.

The goal is to compare two arrays and be sure none of the default placeholder texts exists in the final array. if any default placeholder texts exists, do not allow a form to submit. Each object has a name key that needs to be excluded from the check as it's what renders the component.

Started by using _.isEqual(), but unsure how go about checking each property between the two.

let results = _.isEqual(array1, array2)


Solution

  • You can use _.isEqualWith and customizer function Loadash Ref

    let array1 = [{"name": "componentA","img": "www.url.com/image1.jpg"},{"name": "componentB","header": "this is the default header","text": "here is a default text post","buttons": [{"title": "a button","url": "http://www.url.com"}]},{"name": "componentB","header": "this is the default header 2","text": "here is a default text post 2 ","buttons": [{"title": "a button 2","url": "http://www.url2.com"},{"title": "a second button 2","url": "http://www.url2_1.com"}]}]
    let array2 = [{"name": "componentA","img": "www.url.com/imageA.jpg"},{"name": "componentB","header": "header changed","text": "text post changed","buttons": [{"title": "button changed","url": "http://www.website.com"}]},{"name": "componentB","header": "header 2 changed","text": "here is a default text post 2 ","buttons": [{"title": "button 2 changed","url": "http://www.website2.com"},{"title": "button 2 changed again","url": "http://www.website2_1.com"}]},]
    let array3 = [{"name": "component3","img": "www.url.com/image1.jpg"},{"name": "componentB","header": "this is the default header","text": "here is a default text post","buttons": [{"title": "a button","url": "http://www.url.com"}]},{"name": "componentB","header": "this is the default header 2","text": "here is a default text post 2 ","buttons": [{"title": "a button 2","url": "http://www.url2.com"},{"title": "a second button 2","url": "http://www.url2_1.com"}]}]
    
    
    function check(val1,val2,index){
     if(index === 'name') return true
    }
    
    console.log(_.isEqualWith(array1,array2,check))
    console.log(_.isEqualWith(array1,array3,check))
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>