【问题标题】:Javascript generic method to parse object of different parametrsJavascript泛型方法来解析不同参数的对象
【发布时间】:2017-11-23 02:24:43
【问题描述】:
var data = {
  'id': 'object1',
  'sceneCapability': {
  'updatedAt': '2017-06-19T20:52:45.688Z'
    'currentScene': {
      'value': {
        'number': 1,
        'name': '1'
      }
    },
    'outOfTune': {
      'value': false
    }
  },

  'lightingCapability': {
    'intensity': {
      'value': 0
    }
  },

  'tiltCapability': {
    'command': {
      'value': 'NO'
    },
    'position': {
      'value': 0
    }
  }

// like this I have different types of more than 20 Capabilities 
};

如何编写一个通用方法来解析这个对象?我需要获取currentScene 值、outOfTuneintensitycommandposition 等...

有时我只获得一种能力,有时我获得超过 20 种能力。

我想避免这样做,因为将来可能会有数百种不同的功能

if (obj.lightingCapability && obj.lightingCapability.intensity) {
        console.log(obj.lightingCapability.intensity.value)
}

if (device.sceneCapability && device.sceneCapability.outOfTune) {
            // do something
        }

输出我想要的东西

currentScene:1,
outOfTune: false,
intensity: 0,
command: 'NO',
position: 0

【问题讨论】:

  • 您的密钥是否总是以“能力”一词结尾?
  • @kevin628 是的,它们总是以 Capability 结尾。

标签: javascript angular typescript ecmascript-6 javascript-objects


【解决方案1】:

也许这样的东西对你有用?

一个帮助函数,它找到您需要的属性,如果链上的任何东西都不存在,则返回 null。如果您不喜欢属性名称数组,我添加了两个“不同”版本。

var object = {
    a: {
        b: {
            c: {
                d: 10
            }
        }
    }
};

function getValue(object, propertyPath) {
    var o = object;
    var pLen = propertyPath.length;

    for (var i = 0; i < pLen; i++) {
        var propertyName = propertyPath[i];
        if (!o.hasOwnProperty(propertyName))
            return undefined;

        o = o[propertyName];
    }

    return o;
}

function getValueFromString(object, path) {
    return this.getValue(object, path.split('.'));
}

console.log(getValue(object, ['a', 'b', 'c', 'd']));    //logs 10
console.log(getValueFromString(object, 'a.b.c.d'));     //logs 10
console.log(getValue(object, ['a', 'b', 'c', 'e']));    //logs undefined

【讨论】:

  • 哦,看来你也有同样的想法,并击败了我。包含将键作为字符串的包装器与仅在 getvalue 方法中拆分键相比真的有好处吗?
  • 所以我们在调用这个方法之前需要keyChain,不是吗?只是想知道有没有办法在不知道钥匙链的情况下实现这一点?
  • @Marie 一点也不。之后我在编辑中添加了 getValueFromString 方法,并希望保持简洁。
  • @PratapA.K 只是钥匙,还是到那里的整个钥匙链?也许像 JSON.stringify(object) 这样的东西在这里有用吗?
  • @PratapA.K 检查这个答案,我想它会做你想要的stackoverflow.com/questions/34513964/…
【解决方案2】:

实现此目的的一种稍微笨拙的方法是创建一个帮助函数,该函数允许将钥匙链作为字符串传入并循环遍历它。例如

function getValue(obj, keyChain){
  var keys = keyChain.split('.');
  do {
    var key = keys.shift();
    if (!obj.hasOwnProperty(key)){
      return undefined;
    }
    obj = obj[key];
  } while (keys.length > 0);
  return obj;
}

getValue(data, "lightingCapability.intensity.value")

【讨论】:

  • 所以我们在调用这个方法之前需要keyChain,不是吗?只是想知道有没有办法在不知道钥匙链的情况下实现这一点?
  • 抱歉,我不确定我是否关注。您想在不知道值在哪里的情况下访问特定值?
  • 是的,看起来有点奇怪,因为每个功能都有不同的参数。
【解决方案3】:

根据我们在第一个答案的 cmets 中的讨论,我意识到您的意思有所不同。这应该可以解决问题:

var object = {
    a: {
        b: {
            c: {
                value: 10
            },
            d: {
                e: {
                    value: 20
                }
            }
        }
    }
};

function logAllValues(object) {
    for (var p in object) {
        var o = object[p];
        if (o.value)
            console.log(p + ': ' + o.value);
        else 
            logAllValues(o);
    }
}

logAllValues(object);    //logs c:10 and e:20

【讨论】:

  • 如果值为 fasley,这将失败,那么 o.hasOwnProperty("value") 呢?
【解决方案4】:

我想你只需要安装lodash#get

npm i --save lodash.get

var get = require('lodash.get');

if(get('foo.baz.foobaz')) {
  alert('yep');
}

但您总是需要提前知道您需要的所有paths

重新实现这个经过社区测试的方法最终将导致重新发明轮子,所以,只需安装和使用它。

【讨论】:

    【解决方案5】:

    你可以使用 ES6 的 try and catch 块来实现这样的事情

    var object = {
        a: {
            b: {
                c: {
                    value: 10
                },
                d: {
                    e: {
                        value: 20
                    }
                }
            }
        }
    };
    
    function getValue(jsObject) {
        try {
            return jsObject();
        } catch (e) {
            return undefined;
        }
    }
    

    // 像这样使用它

    getValue(() => object.a.b); // 返回对象 {c: Object, d: Object}

    getValue(() => object.a.b.c); // 返回对象 {value: 10}

    getValue(() => object.a.b.x); // 返回未定义

    【讨论】:

    • 你真的不应该使用 try-catch 来控制这样的逻辑流。
    • 一般是的。代码肯定更干净,但负面情况会严重影响性能。如果可能,您应该使用其他逻辑来避免使用 try-catch 块。
    猜你喜欢
    • 2022-11-12
    • 1970-01-01
    • 1970-01-01
    • 2011-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多