JSON undefined 属性 - 简化验证以避免类型错误
JSON undefined property - simplified validation to avoid TypeErrors
我正在尝试有效地验证多层 json 对象,这些对象可能具有一个或多个未定义的父属性,具体取决于场景。
这是一个对象只有 2 级属性的示例:
scenarioArray = [
{color:{blue:'yes'}},
{color:{green:'no'}},
{colour:{blue:'yes'}} ]; //colour instead of color
所以我想最有效地识别场景的颜色
let color;
let s = randomScenario; //random scenario from the scenarioArray
if(s.color != undefined && s.color.blue != undefined) {
color = s.color.blue;
} else if (s.color != undefined && s.color.green != undefined) {
color = s.color.green;
} else if (s.colour != undefined && s.colour.blue !=undefined) {
color = s.colour.blue;
};
这段代码在技术上是可行的,只是有点乱。
当您将其外推到具有 4-5 级属性的对象时,if 语句变得笨拙且不可读。
我很乐意就如何简化这一点提出建议。
真实世界json对象示例:
addendum.contract.buyerInformation.name
addendum.contract.contract.buyerInformation.name
addendum.contract.purchaser.buyerFirstName
addendum.contract.data.purchaser.buyer.name
frameworks/libraries 使用过:
AngularJS
Lodash
(对任何可以提高效率的建议库开放)
P.S。如果这对 Whosebug 的问题过于开放,请告诉我...
这是一个可以为您查找错误的函数。它最多支持三个级别。它是可配置的。对于第 4 和第 5 级别,您可以扩展它或使其递归以获得无限级别支持:
const validSecondLevels = ['blue', 'red', 'green']
const validThirdLevels = ['yes', 'no']
const validPropertyNames = ['color']
scenarioArray = [
{ color: { bluee: 'yes' } },
{ color: { green: 'invalid-value' } },
{ colour: { blue: 'yes' } }];
function findErrors(scenario) {
var invalidProperties = scenarioArray.filter(function (it) {
var invalidPropertyNames = Object.keys(it).filter(item => !validPropertyNames.includes(item));
if (invalidPropertyNames.length)
return it;
var foundProperties = validPropertyNames.filter(item => it[item]).map(item => it[item]);
var invalids = foundProperties.filter(function (property) {
var invalidSecondLevels = Object.keys(property).filter(item => !validSecondLevels.includes(item));
if (invalidSecondLevels.length)
return property;
var foundValues = validSecondLevels.filter(item => property[item]).map(item => property[item]);
var invalidThirdLevels = foundValues.filter(function (foundValue) {
return !validThirdLevels.includes(foundValue);
});
if (invalidThirdLevels.length)
return property;
});
if (invalids.length)
return it;
});
return invalidProperties;
}
console.log(findErrors(scenarioArray));
不幸的是,JavaScript 在某种程度上缺少原生 autovivification, but it can be emulated via Proxy
。
这是一个笨拙且脆弱的解决方案,但它将任何深度检查减少为两个操作并且应该适用于大多数情况:
'use strict';
const isEmpty = Symbol('isEmpty');
function autoVivify(object = {}) {
Object.defineProperty(object, isEmpty, {
get: () => Object.keys(object).length === 0,
});
Object.keys(object).forEach((key) => {
const val = object[key];
if (typeof val === 'object' && val !== null) object[key] = autoVivify(val);
});
return new Proxy(
object,
{ get: (obj, name) => name in obj ? obj[name] : obj[name] = autoVivify() },
);
}
const scenarioArray = [
{ color: { blue: 'yes' }},
{ color: { green: 'no' }},
{ colour: { blue: 'yes' }},
];
const randomScenario = autoVivify(scenarioArray[0]);
if (randomScenario.color.blue && !randomScenario.color.blue[isEmpty])
console.log(randomScenario.color.blue);
if (randomScenario.color.red && !randomScenario.color.red[isEmpty])
console.log(randomScenario.color.red);
if (randomScenario.color.a.b.c && !randomScenario.color.a.b.c[isEmpty])
console.log(randomScenario.color.a.b.c);
if (randomScenario.colour.green && !randomScenario.colour.green[isEmpty])
console.log(randomScenario.colour.blue);
希望我们很快就会 a more appropriate way。
我正在尝试有效地验证多层 json 对象,这些对象可能具有一个或多个未定义的父属性,具体取决于场景。
这是一个对象只有 2 级属性的示例:
scenarioArray = [
{color:{blue:'yes'}},
{color:{green:'no'}},
{colour:{blue:'yes'}} ]; //colour instead of color
所以我想最有效地识别场景的颜色
let color;
let s = randomScenario; //random scenario from the scenarioArray
if(s.color != undefined && s.color.blue != undefined) {
color = s.color.blue;
} else if (s.color != undefined && s.color.green != undefined) {
color = s.color.green;
} else if (s.colour != undefined && s.colour.blue !=undefined) {
color = s.colour.blue;
};
这段代码在技术上是可行的,只是有点乱。
当您将其外推到具有 4-5 级属性的对象时,if 语句变得笨拙且不可读。
我很乐意就如何简化这一点提出建议。
真实世界json对象示例:
addendum.contract.buyerInformation.name
addendum.contract.contract.buyerInformation.name
addendum.contract.purchaser.buyerFirstName
addendum.contract.data.purchaser.buyer.name
frameworks/libraries 使用过: AngularJS Lodash (对任何可以提高效率的建议库开放)
P.S。如果这对 Whosebug 的问题过于开放,请告诉我...
这是一个可以为您查找错误的函数。它最多支持三个级别。它是可配置的。对于第 4 和第 5 级别,您可以扩展它或使其递归以获得无限级别支持:
const validSecondLevels = ['blue', 'red', 'green']
const validThirdLevels = ['yes', 'no']
const validPropertyNames = ['color']
scenarioArray = [
{ color: { bluee: 'yes' } },
{ color: { green: 'invalid-value' } },
{ colour: { blue: 'yes' } }];
function findErrors(scenario) {
var invalidProperties = scenarioArray.filter(function (it) {
var invalidPropertyNames = Object.keys(it).filter(item => !validPropertyNames.includes(item));
if (invalidPropertyNames.length)
return it;
var foundProperties = validPropertyNames.filter(item => it[item]).map(item => it[item]);
var invalids = foundProperties.filter(function (property) {
var invalidSecondLevels = Object.keys(property).filter(item => !validSecondLevels.includes(item));
if (invalidSecondLevels.length)
return property;
var foundValues = validSecondLevels.filter(item => property[item]).map(item => property[item]);
var invalidThirdLevels = foundValues.filter(function (foundValue) {
return !validThirdLevels.includes(foundValue);
});
if (invalidThirdLevels.length)
return property;
});
if (invalids.length)
return it;
});
return invalidProperties;
}
console.log(findErrors(scenarioArray));
不幸的是,JavaScript 在某种程度上缺少原生 autovivification, but it can be emulated via Proxy
。
这是一个笨拙且脆弱的解决方案,但它将任何深度检查减少为两个操作并且应该适用于大多数情况:
'use strict';
const isEmpty = Symbol('isEmpty');
function autoVivify(object = {}) {
Object.defineProperty(object, isEmpty, {
get: () => Object.keys(object).length === 0,
});
Object.keys(object).forEach((key) => {
const val = object[key];
if (typeof val === 'object' && val !== null) object[key] = autoVivify(val);
});
return new Proxy(
object,
{ get: (obj, name) => name in obj ? obj[name] : obj[name] = autoVivify() },
);
}
const scenarioArray = [
{ color: { blue: 'yes' }},
{ color: { green: 'no' }},
{ colour: { blue: 'yes' }},
];
const randomScenario = autoVivify(scenarioArray[0]);
if (randomScenario.color.blue && !randomScenario.color.blue[isEmpty])
console.log(randomScenario.color.blue);
if (randomScenario.color.red && !randomScenario.color.red[isEmpty])
console.log(randomScenario.color.red);
if (randomScenario.color.a.b.c && !randomScenario.color.a.b.c[isEmpty])
console.log(randomScenario.color.a.b.c);
if (randomScenario.colour.green && !randomScenario.colour.green[isEmpty])
console.log(randomScenario.colour.blue);
希望我们很快就会 a more appropriate way。