如何检查变量是否以特定格式定义?

时间:2019-07-08 10:59:39

标签: javascript

假设我有一个模板变量测试。

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变量只是一个示例,它可以具有任何格式,其中包含任意数量的嵌套对象。

3 个答案:

答案 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)

您可以创建一个函数数组,每个函数带有一个参数,并为每个给定条件返回truefalse。在给定对象的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"]
// }

https://validatejs.org/