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

2020-04-27 13:42:22 +08:00
 RRRoger

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

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

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

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

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

2094 次点击
所在节点    程序员
16 条回复
rrfeng
2020-04-27 13:45:07 +08:00
没学过的很难理解吧?不要高估你的用户。

建议直观一点:

小于 xx 或者 大于 xx
RRRoger
2020-04-27 13:47:10 +08:00
@rrfeng #1 原文:“没学过的很难理解吧?不要高估你的用户。建议直观一点:小于 xx 或者 大于 xx”
======
回复:小于大于要用到好几个字段, 并且不灵活,这只是一个配置, 所以改动的不多, 用户都是本科以上
RRRoger
2020-04-27 13:49:40 +08:00
实在不行, 就自己撸一个简陋版的
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
2020-04-27 13:56:41 +08:00
如果仅限于数字和正负无穷的话,其他表达式直接插 f-string 也可以接受,实现起来似乎并不难,不过估计应该是有人做过,唯一吐槽的就是数学符号在 idle 里打起来麻烦,改成其他约定符号加上运算符重载,理论上应该可以做到直接用表达式完成判断。
littleshy
2020-04-27 13:57:28 +08:00
我配置里也有用到这个,我是直接用正则解析下。
Vegetable
2020-04-27 13:58:24 +08:00
是你觉得直白还是用户觉得直白了?你不觉得键鼠输入表达式很麻烦吗?
前端应该是一个表单输入条件,先选择运算符,<=,再输入值-600,然后单击新增规则,选择运算符>=,输入值 600
RRRoger
2020-04-27 13:59:58 +08:00
@Vegetable #7 原文:“是你觉得直白还是用户觉得直白了?你不觉得键鼠输入表达式很麻烦吗?前端应该是一个表单输入条件,先选择运算符,<=,再输入值-600,然后单击新增规则,选择运算符>=,输入值 600”
======
回复:这个方案是我暂定方案, 我觉得这样会灵活, 而且用户也很容易看懂, 这只是一个配置项
RRRoger
2020-04-27 14:02:43 +08:00
@airfling 谢谢 我研究一下
princelai
2020-04-27 14:30:41 +08:00
我印象中 postgreSQL 可以干这个事情
fkdog
2020-04-27 15:21:25 +08:00
需求很怪。
但是这种自己区间转不等式的自己不能编码解决吗?
daozhihun
2020-04-27 17:33:40 +08:00
我觉得不要用这样的东西去表示,用户好不好理解不说,主要输入也很麻烦。
先不说无穷大,并集符号等问题,用户输入错了是个麻烦事,你怎么提示他少了个括号或者开闭区间的上下界写反了?
向上面说的橹个>=之类的表单更合适
stevenkang
2020-04-27 17:39:31 +08:00
感觉这样容易弄出线上 bug,一会儿这里没输入对,一会儿那里没输入对。
zhuangzhuang1988
2020-04-27 17:45:19 +08:00
RPLY
Licia
2020-04-28 09:29:00 +08:00
∪这种符号输入很麻烦吧,比如我就只会复制
siweipancc
2020-04-28 12:17:02 +08:00
参考一下 guava?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/666592

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX