【问题标题】:Check if javascript object has nested key-value pairs [duplicate]检查javascript对象是否具有嵌套的键值对[重复]
【发布时间】:2021-09-05 10:02:37
【问题描述】:

我返回了一个我事先不知道其结构的对象。我唯一知道的是对象中应该包含哪些值。我的目标不是检查返回的对象是否与另一个对象特别匹配,而是检查返回的对象中是否存在特定的嵌套键值对。

以下是我期望返回的随机对象以及我想要检查的值。是否已经编写了执行此类检查的任何内容?抱歉缺少代码,但我不确定从哪里开始。我考虑过将对象展平并进行检查,但由于数组长度未知,这个想法没有成功。

// ob1 is the random object being returned. This will not be the same every time.
ob1 = {
    key_a: "val_a1",
    key_b: [
        "val_b1",
        "val_b2",
        "val_b3"
    ]
}

ob2a = {
    key_b: [
        "val_b2"
    ]
}

ob2b = {
    key_a: "val_a1",
    key_b: [
        "val_b3"
    ]
}

ob2c = {
    key_b: [
        "val_b2"
        "val_b3"
    ]
}

ob2d = {
    key_b: [
        "val_b1",
        "val_doesnt exist"
    ]
}

ob2e = {
    key_b: "val_b1"
}

checkExists(ob1,ob2a) // true
checkExists(ob1,ob2b) // true
checkExists(ob1,ob2c) // true
checkExists(ob1,ob2d) // false
checkExists(ob1,ob2e) // false

【问题讨论】:

  • 使用Object.entries.every() 遍历测试对象中的条目。对于它们中的每一个,检查属性是否存在于第一个对象中,如果存在,值是否匹配。

标签: javascript node.js javascript-objects


【解决方案1】:
    function checkIfExists(list1, list2) {
      let output = list2.filter(a=>!list1.some(b=>a==b))
      if(output.length==0) {
        return true;
      }
      return false
    }

   console.log(checkIfExists(ob1.key_b, ob2b.key_b))

您可以添加检查 ob2b.key_b 是否存在以及是否为数组。请注意,根据您的问题,它仅适用于数组。

【讨论】:

  • 解决方案似乎过于复杂。这是一个简化版本的建议:const checkIfExists = (list1, list2) => list2.every(a => list1.includes(a))
【解决方案2】:

如果我在您的示例中正确理解了您,ob1 是您要比较每个其他 ob2a、...、ob2e 的对象。

这是我想出的:

const checkExists = (ob1, ob2) => {
    // Filter for only matched keys between the two objects
    const matchedKeys = Object.keys(ob1).filter(key => {
        if(ob2[key] !== undefined) return key;
    });

    // No matched keys found so there are no nested key-value pairs 
    if(matchedKeys.length === 0) return false;
    else {
        let result = true;
        matchedKeys.forEach(key => {
            const ob1CurrentValue = ob1[key];
            const ob2CurrentValue = ob2[key];

            // Case: both values are arrays
            if(Array.isArray(ob1CurrentValue) && (Array.isArray(ob2CurrentValue))) {
                ob2CurrentValue.forEach(value => {
                    // If 1 value is not found result is false
                    if(!ob1CurrentValue.includes(value)) {
                        result = false;
                    }
                });
            // Case: both values are objects
            } else if(typeof ob1CurrentValue === 'object' && typeof ob2CurrentValue === 'object') {
                result = result && checkExists(ob1[key], ob2[key]);
            } else {
                result = ob1CurrentValue === ob2CurrentValue;
            }
        });

        return result;
    }
}

const ob1 = {key_a: "val_a1", key_b: ["val_b1", "val_b2", "val_b3"]};
const ob2a = {key_b: ["val_b2"]};
const ob2b = {key_a: "val_a1", key_b: ["val_b3"]};
const ob2c = {key_b: ["val_b2","val_b3"]};
const ob2d = {key_b: ["val_b1", "val_doesnt exist"]};
const ob2e = {key_b: "val_b1"};
const ob2f = {key_c: "val_c1"};
const ob2g = {key_c: "val_c1", key_b: "val_b1"};
const ob2h = {key_c: "val_b1", key_b: "val_b1"};
const ob2i = {key_a: "val_a1", key_b: ["val_b1", "val_b2", "val_b3"], key_c: { key_c1: ["val_c1_1"], key_c2: ["val_c2_1"]}};
const ob2j = {key_c: {key_c1: ["val_c1_1"]}};
const ob2k = {key_a: "val_a11"};
const objl = {key_a: "val_a11", key_c: {"key_c1":["val_c1_1"]}};

console.log(checkExists(ob1, ob2a)); // true
console.log(checkExists(ob1, ob2b)); // true
console.log(checkExists(ob1, ob2c)); // true
console.log(checkExists(ob1, ob2d)); // false
console.log(checkExists(ob1, ob2e)); // false
console.log(checkExists(ob1, ob2f)); // false
console.log(checkExists(ob1, ob2g)); // false
console.log(checkExists(ob1, ob2h)); // false
console.log(checkExists(ob2i, ob2j)); // true
console.log(checkExists(ob2i, ob2k)); // false
console.log(checkExists(ob2i, objl)); // false

我首先在比较对象之间查找匹配的键,如果有匹配的键,我检查ob1 是否包含每个键的ob2 的所有值。

我还尝试涵盖更多案例,例如:

ob2f = {
    key_c: "val_c1"
}

ob2g = {
    key_c: "val_c1",
    key_b: "val_b1"
}

ob2h = {
    key_c: "val_b1",
    key_b: "val_b1"
}

我不知道这些是否与您相关。

【讨论】:

  • 这不适用于嵌套的键值对。如果 ob1 更改为 '{"key_a":"val_a1","key_b":["val_b1","val_b2","val_b3"],"key_c":{"key_c1":["val_c1_1"],"key_c2 ":["val_c2_1"]}}' 然后搜索 '{"key_c":{"key_c1":["val_c1_1"]}}' 会失败。
  • 我也更新了这些案例的代码。
  • '{"key_a":"val_a11","key_c":{"key_c1":["val_c1_1"]}}' 通过,但应该失败。我会看看我是否可以修补它。
  • 我再次更新了代码,检查它现在是否适合您的案例。在您的问题中我不清楚的是,如果 ob1 和 ob2 具有相同的键,则值必须是相同的类型?
  • 似乎有效。是的,相同的类型,这似乎是你的工作方式。 {key_c: {key_c1:"val_c1_1"}} 失败,{key_c: {key_c1:["val_c1_1"]}} 通过,应该是这样。谢谢您的帮助。另外,我不知道为什么这个问题被标记为重复,因为它根本不像引用的已经回答的问题。
猜你喜欢
  • 2014-08-22
  • 2014-05-08
  • 2012-06-05
  • 2020-02-03
  • 2022-06-30
  • 2020-04-27
  • 2020-02-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多