假设我有一个模板变量测试。
test = {
key1: "String",
key2: {
key1: Int,
key2: ["Array","of","Strings"]
},
key3: [0,1,2...], // Array of Integers
key4: true // Boolean value
}
现在,我想检查一个变量是否具有与该模板完全相同的“格式”,这意味着它需要有4个键,一个键必须是字符串, 一个键必须是包含2个键(整数和字符串数组)的Object,一个键必须是整数数组,一个键必须具有布尔值。
例如,此变量的格式不是test
模板变量的格式。
example = {
key1: "String",
key2: "String",
key3: "String"
}
是否可以将变量的结构与另一个变量的结构进行比较,以确保其格式正确,例如可以将AJAX调用发送到服务器而格式没有问题?< / p>
注意:template变量只是一个示例,它可以具有任何格式,其中包含任意数量的嵌套对象。
答案 0 :(得分:2)
您可以仅对属性进行比较,然后调用该函数并检查属性类型是否匹配。
每条评论我都将递归添加到更深的层次。
您还必须检查对象是否为数组。我将把这个Array.isArray(value)
留给您,以将其放置在正确的位置。
let basething = {
key1: "String",
key2: {
key1a: 4,
key2arr: ["Array", "of", "Strings"]
},
key3arr: [0, 1, 2], // Array of Integers
key4: true // Boolean value
};
let test = {
key1: "String",
key2: {
key1a: 98,
key2arr: ["Array", "of", "Strings", "not exact"]
},
key3arr: [0, 1, 2, 5, 6, 123], // Array of Integers
key4: true // Boolean value
};
let example = {
key1: "String",
key2: "String",
key3: "String"
}
function compareProperty(object1, object2) {
let sameStruct = true;
for (let p in object1) {
console.log(p,typeof object1[p]);
// compare property
if (!object2.hasOwnProperty(p)) {
sameStruct = false;
} else {
if (object2.hasOwnProperty(p)) {
if (typeof object1[p] == "object" && typeof object2[p] == "object") {
sameStruct = sameStruct && compareProperty(object1[p], object2[p]);
} else {
// compare type of property
sameStruct = sameStruct && (typeof object2[p] === typeof object1[p]);
}
} else {
sameStruct = false;
}
}
}
return sameStruct;
}
let isSame = compareProperty(basething, example);
let isSame2 = compareProperty(basething, test);
console.log(isSame, isSame2);
答案 1 :(得分:2)
您可以创建一个函数数组,每个函数带有一个参数,并为每个给定条件返回true
或false
。在给定对象的every()
上使用Object.values
,并检查是否有任何函数对该值返回true。
const test = {
key1: "String",
key2: {
key1: 55,
key2: ["Array","of","Strings"]
},
key3: [0,1,2], // Array of Integers
key4: true // Boolean value
}
let cons = [
x => x.constructor === String,
x => x.constructor === Array && x.every(a => typeof a === "number"),
x => x.constructor === Boolean,
x => {
if(x.constructor === Object){
let funs = [
(x) => x.constructor === Number,
(x) => x.every(x => x.constructor === String)
]
return testFormat(x,funs)
}
}
]
function testFormat(obj, funs){
let vals = Object.values(obj);
return vals.length === funs.length && vals.every(x => funs.some(f => f(x)));
}
console.log(testFormat(test, cons))
答案 2 :(得分:0)
我认为https://validatejs.org/可以为您提供帮助。
Sometimes it's nice to be able validate field differently depending on the input itself. validate.js allows the validators object and validator options to be a function that should return the constraints/options:
var constraints = {
username: {
presence: true,
exclusion: {
within: ["nicklas"],
message: "'%{value}' is not allowed"
}
},
password: {
presence: true,
length: {
minimum: 6,
message: "must be at least 6 characters"
}
}
};
validate({password: "bad"}, constraints);
// => {
// "username": ["Username can't be blank"],
// "password": ["Password must be at least 6 characters"]
// }