【问题标题】:Joi validate order of arrayJoi验证数组的顺序
【发布时间】:2019-09-03 19:19:34
【问题描述】:

我查看了 Joi API,但没有数组顺序之类的东西。我还研究了 Joi refs,但目前不可能(如果我错了,请纠正我)在数组中使用它们。

我正在考虑使用extend,但不确定是否可以检索整个数组。

输入:

const asc = [1,2,3];
const noOrder = [10,7,8];
const desc = [6,5,4];

期望的输出:

Joi.validate(asc, Joi.array().asc()) // True
Joi.validate(asc, Joi.array().desc()) // False
Joi.validate(desc, Joi.array().desc()) // False
Joi.validate(noOrder, Joi.array().desc()) // False
Joi.validate(noOrder, Joi.array().asc()) // True

所以我的问题是,我该如何开始呢?任何想法都非常感谢

【问题讨论】:

  • 你试过array.ordered
  • @CodeManiac 问题是数组的长度是可变的
  • 我猜你可以扩展类似于array.unique 工作值和函数的方式
  • @CodeManiac 可能类似于 Joi.array().unique((a,b) => a <= b)

标签: javascript joi


【解决方案1】:

As of v16.0.0,Joi 支持使用以下模式验证数组的顺序:

Joi.array()
    .items(Joi.number())
    .sort({ order: 'ascending' });

【讨论】:

    【解决方案2】:

    Joi 不提供任何内置方法来验证数组的顺序,因此您必须使用自己的扩展名 extend,如下所示:

    const Joi = require('joi');
    
    const customJoi = Joi.extend((joi) => ({
      base: joi.array(),
      name: 'array',
      language: {
          asc: 'needs to be sorted in ascending order',
          desc: 'needs to be sorted in descending order'
      },
    
      rules: [
          {
              name: 'asc',        
              validate(params, value, state, options) { 
                const isAscOrder = value.every((x, i) => i === 0 || x >= value[i - 1]);
                return isAscOrder ? value : this.createError('array.asc', {v: value}, state, options);             
              }
          },
          {
              name: 'desc',          
              validate(params, value, state, options) {
                const isDescOrder = value.every((x, i) => i === 0 || x <= value[i - 1]);
                return isDescOrder ? value : this.createError('array.desc', {v: value}, state, options);             
              }
          }
      ]
    }));
    
    const ascSchema = customJoi.array().asc();
    const descSchema = customJoi.array().desc();
    
    // Validation results.
    console.log(Joi.validate([5, 7, 9, 10], ascSchema)); //true
    console.log('\n\n');
    console.log(Joi.validate([5, 7, 6, 10], ascSchema)); //false
    console.log('\n\n');
    console.log(Joi.validate([5, 4, 2, 0], descSchema)); //true
    console.log('\n\n');
    console.log(Joi.validate([5, 4, 2, 6], descSchema)); //false
    

    【讨论】:

    • 您好,感谢您的回答。快速提问,使用forEach() 然后使用createError 会比使用every 更高效吗?甚至是for 循环?
    • 不客气。 Every 方法一旦发现一个不满足条件的元素,就会停止检查数组元素。您可以使用foreachfor 循环实现相同的行为,但是您必须显式地中断循环,因此解决方案将更加冗长。 every 的另一个好处是传递的函数通常是没有副作用的纯函数。您可以在此处查看有关每种数组方法之间差异的更多信息:stackoverflow.com/questions/7340893/…
    • 感谢您提供有用的链接。接受答案
    • 干杯@BrianLe!回头见。
    猜你喜欢
    • 2021-02-05
    • 2017-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-11
    • 1970-01-01
    • 2018-09-24
    相关资源
    最近更新 更多