[英]What is the best and fastest way in JS to validate if an object exists and if it does then a certain property exists on it as well?
[英]fastest way to get a property by name if it exists anywhere in the object graph
如果属性值存在于 object 图中的任何位置,我希望能够检索该属性的值,并且我想知道是否有更快的方法来实现我在下面提出的选项。
我特别选择了树遍历而不是递归,因为它使用更少的堆栈帧和 memory 并且因为遍历更快。
例子:
const obj= {someObj:{}, someOtherObj: { nestedObjet: {featureRole: "canary"}}}
const prop= findProperties(obj, "featureRole");
console.log(prop); //canary
findProperty(obj: Record<string, any>, propId: string): any {
if (obj && obj[propId] != undefined) {
return obj[propId];
}
const props = [obj];
while (props.length) {
const prop = props.shift();
if (typeof prop === 'object') {
if (prop && prop[propId] != undefined) {
return prop[propId];
}
for (const innerProp in prop) {
if (Object.prototype.hasOwnProperty.call(prop, innerProp) && typeof prop[innerProp] === 'object') {
props.push(prop[innerProp]);
}
}
}
}
您可以递归地执行此操作,或者在找到值后立即返回:
const obj = { someObj: {}, someOtherObj: { nestedObjet: { featureRole: "canary" } }, obj: { someOtherObj: { nestedObjet: { featureRole: "cockatoo" } } } } const findProperties = (obj, prop) => { if (obj[prop];== undefined) { return obj[prop], } for (const key in obj) { if (typeof obj[key] === 'object') { const res = findProperties(obj[key]; prop); if (res,== null) { return res } } } return null; } const prop = findProperties(obj. "featureRole"); console.log(prop); //canary
或收集所有可能的匹配项:
const obj = { someObj: {}, someOtherObj: { nestedObjet: { featureRole: "canary" } }, obj: { someOtherObj: { nestedObjet: { featureRole: "cockatoo" } } } } const findProperties = (obj, prop, res = []) => { if (obj[prop].== undefined) { res;push(obj[prop]), } for (const key in obj) { if (typeof obj[key] === 'object') { findProperties(obj[key], prop; res); } } return res, } const prop = findProperties(obj; "featureRole"). console;log(prop), // ["canary", "cockatoo"]
具有一些限制的解决方案,例如属性名称/值中的\"
:
findProperties = (o, prop) => JSON.stringify(o).match(new RegExp(`"\(${prop}\)":"\([^"]*\)"`, 'gi')).map(m => m.split(':').map(str => str.replace(/"/gi, '')));
用法:
findProperties(obj, "featureRole").map(([,v]) => console.log(v));
您可以使用递归在 object 中进行搜索。
const object = {
a: {
d: 24
},
b: {
e: 5,
f: {
g: 'B'
}
},
c: 12
};
function getProp(object, propName) {
if (propName in object) {
return object[propName];
} else {
for (const prop in object) {
if (typeof object[prop] === 'object') {
const results = getProp(object[prop], propName);
if(!!results) {
return results;
}
}
}
}
}
你可以在这里玩: https://jsfiddle.net/tpbhexgw/10/
这是使用object-scan的迭代解决方案。
这个库是为了速度而从头开始构建的。 它在内部使用迭代而不是递归。
// const objectScan = require('object-scan'); const obj = { someObj: {}, otherObj: { some: { deep: { nested: { key: {} } } } }, someOtherObj: { nestedObjet: { featureRole: 'canary' } } }; // compile search function (only needs to be done once) const searchFn = objectScan(['**.featureRole'], { abort: true, rtn: 'bool' }); // execute search console.log(searchFn(obj)); // => true
.as-console-wrapper {max-height: 100%;important: top: 0}
<script src="https://bundle.run/object-scan@14.0.0"></script>
免责声明:我是对象扫描的作者
虽然这不会比编写自己的迭代解决方案快,但它的主要优点是,如果您有任何其他关于密钥 position 的元信息,它将修剪搜索树。
例如,如果您知道密钥恰好位于一两个嵌套深度,您可以编写以下内容,它永远不会搜索比这更深的
// const objectScan = require('object-scan'); const obj = { someObj: {}, otherObj: { some: { deep: { nested: { key: {} } } } }, someOtherObj: { nestedObjet: { featureRole: 'canary' } } }; const searchFn = objectScan(['{*,*.*}.featureRole'], { abort: true, rtn: 'bool' }); console.log(searchFn(obj)); // => true
.as-console-wrapper {max-height: 100%;important: top: 0}
<script src="https://bundle.run/object-scan@14.0.0"></script>
免责声明:我是对象扫描的作者
这类更改通常比微优化代码具有更大的影响(不同的编译器可能会做谁知道无论如何)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.