V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
RRRoger
V2EX  ›  程序员

有没有解析集合表达式的轮子 例如:`(-∞, -600]∪[600, +∞)`

  •  
  •   RRRoger · 2020-04-27 13:42:22 +08:00 · 2014 次点击
    这是一个创建于 1466 天前的主题,其中的信息可能已经有所发展或是发生改变。

    业务里有判断一个数是否在一个区间需求, 要求可以动态配置,

    要是写成(-∞, -600]∪[600, +∞)这样,

    对用户(理解集合的意义)会直白很多,

    并且在数据库里保存一个 char 类型的字段就可以通用.

    问: 有没有类似的轮子,最好技术栈是python.

    16 条回复    2020-04-28 12:17:02 +08:00
    rrfeng
        1
    rrfeng  
       2020-04-27 13:45:07 +08:00
    没学过的很难理解吧?不要高估你的用户。

    建议直观一点:

    小于 xx 或者 大于 xx
    RRRoger
        2
    RRRoger  
    OP
       2020-04-27 13:47:10 +08:00
    @rrfeng #1 原文:“没学过的很难理解吧?不要高估你的用户。建议直观一点:小于 xx 或者 大于 xx”
    ======
    回复:小于大于要用到好几个字段, 并且不灵活,这只是一个配置, 所以改动的不多, 用户都是本科以上
    RRRoger
        3
    RRRoger  
    OP
       2020-04-27 13:49:40 +08:00
    实在不行, 就自己撸一个简陋版的
    airfling
        4
    airfling  
       2020-04-27 13:54:06 +08:00
    这个其实几段代码就可以代码,不知道 python 有没有 java 中的继承。

    ~~~
    public enum IntervalType implements ValueObject<IntervalType> {
    /**
    * 默认,最原始支持的模式
    */
    DEFAULT("默认", 2, new Default()),
    /**
    * 等值
    */
    EQ("=a", 1, new Equal()),
    /**
    * 不等于
    */
    NOT_EQ("!=a", 1, new NotEqual()),
    /**
    * 大于
    */
    GT(">a", 1, new GraterThan()),
    /**
    * 小于
    */
    LT("<a", 1, new LessThan()),
    /**
    * 大于等于
    */
    GT_EQ(">=a", 1, new GraterThanAndEqual()),
    /**
    * 小于等于
    */
    LT_EQ("<=a", 1, new LessThanAndEqual()),
    /**
    * 范围
    */
    BETWEEN("∈[a,b]", 2, new Between()),
    /**
    * 左开范围
    */
    LEFT_BETWEEN("∈(a,b]", 2, new LeftOpenBetween()),
    /**
    * 右开范围
    */
    RIGHT_BETWEEN("∈[a,b)", 2, new RightOpenBetween()),
    /**
    * 双开范围
    */
    OPEN_BETWEEN("∈(a,b)", 2, new OpenBetween());

    private String value;

    private Interval interval;

    private int valueNumber;

    /**
    * 此方法在页面调用
    *
    * @return number
    */
    @SuppressWarnings("unused")
    public int getValueNumber() {
    return valueNumber;
    }

    public String getValue() {
    return value;
    }

    /**
    * 获取转换后的区间
    *
    * @param alertType 报警类型
    * @param values 相关阈值
    * @return 区间
    */
    public String getInterval(int alertType, String... values) {
    return this.interval.convert(alertType, values);
    }

    /**
    * 与{@link #getInterval 相反的一个方法}
    *
    * @param interval 区间
    * @return 报警相关的阈值
    */
    public String[] resolveInterval(String interval) {
    if (this.interval instanceof Default) {
    return PattenUtils.reverseResolve(interval);
    }
    return PattenUtils.regexNumber(interval);
    }

    IntervalType(String value, int valueNumber, Interval interval) {
    this.value = value;
    this.valueNumber = valueNumber;
    this.interval = interval;
    }

    @Override
    public boolean sameValueAs(final IntervalType other) {
    return this.equals(other);
    }

    public class GraterThan implements Interval {

    @Override
    public String convert(int alertType, String... number) {
    return "(" + number[0] + ",∞)";
    }
    }

    ~~~
    lithbitren
        5
    lithbitren  
       2020-04-27 13:56:41 +08:00
    如果仅限于数字和正负无穷的话,其他表达式直接插 f-string 也可以接受,实现起来似乎并不难,不过估计应该是有人做过,唯一吐槽的就是数学符号在 idle 里打起来麻烦,改成其他约定符号加上运算符重载,理论上应该可以做到直接用表达式完成判断。
    littleshy
        6
    littleshy  
       2020-04-27 13:57:28 +08:00
    我配置里也有用到这个,我是直接用正则解析下。
    Vegetable
        7
    Vegetable  
       2020-04-27 13:58:24 +08:00
    是你觉得直白还是用户觉得直白了?你不觉得键鼠输入表达式很麻烦吗?
    前端应该是一个表单输入条件,先选择运算符,<=,再输入值-600,然后单击新增规则,选择运算符>=,输入值 600
    RRRoger
        8
    RRRoger  
    OP
       2020-04-27 13:59:58 +08:00
    @Vegetable #7 原文:“是你觉得直白还是用户觉得直白了?你不觉得键鼠输入表达式很麻烦吗?前端应该是一个表单输入条件,先选择运算符,<=,再输入值-600,然后单击新增规则,选择运算符>=,输入值 600”
    ======
    回复:这个方案是我暂定方案, 我觉得这样会灵活, 而且用户也很容易看懂, 这只是一个配置项
    RRRoger
        9
    RRRoger  
    OP
       2020-04-27 14:02:43 +08:00
    @airfling 谢谢 我研究一下
    princelai
        10
    princelai  
       2020-04-27 14:30:41 +08:00
    我印象中 postgreSQL 可以干这个事情
    fkdog
        11
    fkdog  
       2020-04-27 15:21:25 +08:00
    需求很怪。
    但是这种自己区间转不等式的自己不能编码解决吗?
    daozhihun
        12
    daozhihun  
       2020-04-27 17:33:40 +08:00
    我觉得不要用这样的东西去表示,用户好不好理解不说,主要输入也很麻烦。
    先不说无穷大,并集符号等问题,用户输入错了是个麻烦事,你怎么提示他少了个括号或者开闭区间的上下界写反了?
    向上面说的橹个>=之类的表单更合适
    stevenkang
        13
    stevenkang  
       2020-04-27 17:39:31 +08:00
    感觉这样容易弄出线上 bug,一会儿这里没输入对,一会儿那里没输入对。
    zhuangzhuang1988
        14
    zhuangzhuang1988  
       2020-04-27 17:45:19 +08:00
    RPLY
    Licia
        15
    Licia  
       2020-04-28 09:29:00 +08:00
    ∪这种符号输入很麻烦吧,比如我就只会复制
    siweipancc
        16
    siweipancc  
       2020-04-28 12:17:02 +08:00 via iPhone
    参考一下 guava?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2168 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 05:25 · PVG 13:25 · LAX 22:25 · JFK 01:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.