检查嵌套对象的所有 key/value paris 是否存在于对象数组中

Check if all the key/value paris of a nested object are present in an array of objects

我有以下格式的一些数据:

const data = [
    {
        "region": "London",
        "code": "0",
        "airport": "Heathrow",
        "messages": [
            {
                "date": 1617063225,
                "region": "London",
                "message": "This is a test message"
            }
        ]
    },
    ... // 300 more objects in the same format
]

我想测试上面的数组是否包含一个对象,其中所有 key/values 作为这个部分对象:

const obj = {
    "region": "London",
    "airport": "Heathrow",
    "messages": [
        {
            "region": "London",
            "message": "This is a test message"
        }
    ]
}

注意 obj 不具有 data 中对象的所有属性,这同样适用于 messages 数组 - 缺少一些属性(如 date).为了测试 data 是否包含 obj 的所有属性,我尝试了以下操作:

const exists = data.some(0 => {
   return Object.keys(obj).some(k => {
       return Object.keys(o).indexOf(k)>-1 && obj[k]===o[k];
   });
});

上面只检查了一层深度,即 messages 数组没有进行深度比较。

因为我想要 Jest 这个,所以我也尝试了以下方法:

expect(data).toEqual(
   expect.arrayContaining([
       expect.objectContaining(obj)
   ])
);

上面的第二种方法没有考虑 messages 数组中对象的缺失属性。

有人可以帮我实现上述目标吗?

你可以这样做:

for(*loop through array*) {
    if(!obj[i].region === undefined) {
       //This object would be miising data
       //Do this for every key
    }
}

如果嵌套数组中有多个对象,这里有一个解决方案,用于比较 data 和 obj。

const data = [{
    "region": "London",
    "code": "0",
    "airport": "Heathrow",
    "messages": [{
      "date": 1617063225,
      "region": "Londonn",
      "message": "This is a test messageee"
    },{
      "date": 1617063225,
      "region": "London",
      "message": "This is a test message"
    },{
      "date": 1617063225,
      "region": "London",
      "message": "This is a test message"
    }]
  },
  {
    "region": "London",
    "code": "1",
    "airport": "Heathrow",
    "messages": [{
      "date": 1617063226,
      "region": "London",
      "message": "This is a test message"
    },{
      "date": 1617063225,
      "region": "London",
      "message": "This is a test message"
    },{
      "date": 1617063225,
      "region": "London",
      "message": "This is a test message"
    }]
  }
]

const obj = {
  "region": "London",
  "airport": "Heathrow",
  "messages": [{
    "region": "London",
    "message": "This is a test message"
  },{
    "region": "Londonn",
    "message": "This is a test messageee"
  },{
    "region": "London",
    "message": "This is a test message"
  }]
}
function compareObj(x, y) {
   let objectsAreSame = true;
   for(let prop in x) {
      if(x[prop] !== y[prop]) {
         objectsAreSame = false;
         break;
      }
   }
   return objectsAreSame;
}
const compare = (data, obj)=> {
  return data.some(o => {
    return Object.keys(obj).every(k => {
      if (Array.isArray(obj[k])) {
         let cond
          for(let i=0; i<obj[k].length; i++){
            o[k].some(el => {
              return cond = compareObj(obj[k][i], el)
            })  
            if(cond === false) return cond
          }
          return cond;
      } else {
        return obj[k] === o[k]
      }
    });
  });
}

console.log(compare(data, obj))

你可以这样做。但这仅适用于嵌套数组中只有一个对象的情况。如果需要,您可以调整它以循环播放它。

const data = [{
    "region": "London",
    "code": "0",
    "airport": "Heathrow",
    "messages": [{
      "date": 1617063225,
      "region": "London",
      "message": "This is a test message"
    }]
  },
  {
    "region": "Londonn",
    "code": "1",
    "airport": "Heathrow",
    "messages": [{
      "date": 1617063226,
      "region": "London",
      "message": "This is a test messageee"
    }]
  }
]

const obj = {
  "region": "London",
  "airport": "Heathrow",
  "messages": [{
    "region": "London",
    "message": "This is a test message"
  }]
}

const compare = (data, obj)=> {
  return data.some(o => {
    return Object.keys(obj).every(k => {
      if (Array.isArray(obj[k])) {
        return compare(o[k], obj[k][0])
      } else {
        return obj[k] === o[k]
      }
    });
  });
}

console.log(compare(data, obj))