如何在没有循环的情况下测试我的json的任何属性是否具有特定的子属性?

时间:2013-09-13 22:15:08

标签: javascript json loops

考虑一个例子:

food : {
    cheese: { taste: "delicious", smell: "smelly" },
    bacon:  { taste: "godly", smell: "godly" }
}

我想要一个无环测试,看看是否有任何“食物”的特性(奶酪和/或培根)具有“虔诚”的“味道”。

在这种情况下,它会是肯定的。测试“恶心”应该导致错误,因为没有品味:“恶心”

我的问题实际上围绕着一个无循环的解决方案,因为在几个循环层中的一百个属性json是坏的:(

3 个答案:

答案 0 :(得分:3)

  

我想要一个无环测试,看看是否有任何“食物”的特性(奶酪和/或培根)具有“虔诚”的“味道”。

你做不到。假设您已将JSON反序列化为对象图,则必须有一个循环,因为您必须单独测试对象。<​​/ p>

如果您没有将JSON反序列化为对象图(或者如果您想将该图表反馈回JSON.stringify,尽管我不推荐它 - 因为涉及一个循环),如果你仍然有文本,那么它可以使用正则表达式,例如:

if (jsontext.match(/\b"taste"\s*:\s*"godly"/) {
    // ...something has a taste that is "godly"
}

请注意,在上面,我假设有效的JSON。您的问题没有有效的JSON,因为taste不是双引号,这在JSON中是必需的。

  

我的问题实际上围绕着一个无循环的解决方案,因为在几个循环层中的一百个属性json是坏的:(

那么,你需要让任何负责JSON的人重新设计它。

答案 1 :(得分:2)

您可以通过循环一次来预先索引所有数据:

var tastes = {}, smells = {};
for (var prop in food) {
    if (food.hasOwnProperty(prop) {
        var item = food[prop];
        if (!tastes[item.taste]) { tastes[item.taste] = [] };
        tastes[item.taste].push(prop);
        if (!smells[item.smell]) { smells[item.smell] = [] };
        tastes[item.smell].push(prop);
    }
}

然后,将来,你可以:

if (tests.godly) { ... }

...这样可以避免在每个时间内遍历数据,但是你无法完全消除循环。

答案 2 :(得分:0)

在这种情况下,循环是必要的。

function checkTaste(obj, keyToCheck, valToCheck) {
    for (var key in obj) {
        if (key === keyToCheck && obj[key] === valToCheck) {
            return true;
        }
    }
    return false;
}

checkKey(food, 'taste', 'godly');