各位大佬,请教一个问题 这种日志树是怎么生成的? 。。。 发现了一个问题 V2EX 无法发图片 算了 直接看他的返回格式
com.cityminsu.rba.baseinfo.api.vo.ProductVo
├──价格结束时间:'Mon Nov 15 00:00:00 CST 2021'->'Tue Mar 22 16:29:00 CST 2022'
├──产品状态:'下架'->'上架'
├──规则模版
│    ├──是否可退:'取消扣全款'->'限时取消'
│    ├──rbaRatePlanScope
│    │    └──rbaRatePlanScopeList
│    │         ├──:添加 '[houseList=[0]=0;orgId=0]'
│    │         └──:删除 '[houseList=[0]=0;orgId=0]'
│    └──stayDaysProduct:添加 '[[StayDaysProductVo{productId=null, stayDays=2, discountRatio=80, productStatus=1, active=0}]=[active=0;discountRatio=80;productStatus=1;stayDays=2];[StayDaysProductVo{productId=null, stayDays=3, discountRatio=79, productStatus=1, active=0}]=[active=0;discountRatio=79;productStatus=1;stayDays=3];[StayDaysProductVo{productId=null, stayDays=5, discountRatio=77, productStatus=1, active=0}]=[active=0;discountRatio=77;productStatus=1;stayDays=5];[StayDaysProductVo{productId=null, stayDays=7, discountRatio=75, productStatus=1, active=0}]=[active=0;discountRatio=75;productStatus=1;stayDays=7]]'
├──价格开始时间:'Wed Aug 18 00:00:00 CST 2021'->'Wed Aug 18 16:29:00 CST 2021'
├──平日价:'0.00'->'1000.00'
└──周末价:'0.00'->'1000.00'
  覆盖方式: '不覆盖日历上单独设立价格'
可以看到他返回的就是这种树状结构 请问是怎么实现的
|      1ztoben OP 这种利用 “\n” 和“|”实现的树状结构 | 
|      2ztoben OP 彦祖们 有没有思路啊 别光看看啊 | 
|  |      3Building      2021-08-19 12:00:42 +08:00 via iPhone 如果上过 C 语言课程,作业就有打印各种形状的星星… | 
|  |      4ColinZeb      2021-08-19 13:45:03 +08:00 记录的时候带上 Scope,打印就简单了 | 
|      7szyp      2021-08-19 13:53:56 +08:00  1 python 可以使用 rich.tree  https://github.com/willmcgugan/rich | 
|      9reallittoma      2021-08-19 14:08:49 +08:00 @ztoben 输出跟返回有区别吗 | 
|      10ztoben OP @reallittoma 有道理 | 
|  |      11qwq11      2021-08-19 14:34:21 +08:00 这个不就是序列化一下吗,定义一个 interface{ GetStructuralInfomation() } 返回一个节点的这样的树,递归调用就行了,还可以给每个字段加个 annotation 自动识别名字和格式,就更简单了 | 
|  |      12qwq11      2021-08-19 15:00:58 +08:00 ```javascript function getDescString(o, indent) { switch (typeof (o)) { case 'object': let arr = [] if (Array.isArray(o)) { for (let i = 0; i < o.length; i++) { arr.push(`${indent}- ${i}: ${getDescString(o[i], indent + ' ')}`) } } else { for (var item in o) { arr.push(`${indent}${item}: ${getDescString(o[item], indent + ' ')}`) } } return '\n' + arr.join('\n') default: return o } } let obj = { "msg": "就这样", "tips": [{ "id": 1, "content": "代码挺乱嘻嘻" }, { "id": 2, "content": "再来一个提示" }] } console.log(getDescString(obj, '')) ``` 发现稍微改下就可以生成 yaml ( | 
|      14ztcaoll222      2021-08-19 15:39:03 +08:00 ```java @Orrvide public String toString() { this.class.getFieldss().forEach(it -> { var annotation = it.getAnnotation(XX.class); if (annotation == null) { sout("|--" + field.name + ":" + field.get(this).toString()) } else { sout("|--" + annotation.value + ":" + field.get(this).toString()) } }) } ``` 伪代码,你将就看,其中数组这些可能要特殊处理一下 | 
|      15ztcaoll222      2021-08-19 16:01:33 +08:00 盲写还是有问题,这样,细微的自己调,继承这个接口就行了 ```java public interface Printer { default String toString(int dept) throws IllegalAccessException { String prefix = ""; if (dept != 0) { prefix = "|" + " ".repeat(dept * 2); } StringBuilder sb = new StringBuilder(); for (Field field : this.getClass().getDeclaredFields()) { field.setAccessible(true); Object value = field.get(this); if (value instanceof Printer) { sb.append(prefix).append("├──").append(field.getName()).append(": ").append("\n").append(((Printer) value).toString(dept + 1)); } else { sb.append(prefix).append("├──").append(field.getName()).append(": ").append(value.toString()).append("\n"); } } return sb.toString(); } } ``` | 
|  |      16summerLast      2021-08-19 17:56:20 +08:00 不是很复杂 伪代码 function log(obj,level,isLast){ for(let k in obj){ // TODO isLast let isLast if(obj[k] is Object){ log(obj[k],level+1,isLast) }else{ console.log(isLast?'└':'├',"- ".repeat(level),k,":",obj[k]) } } } | 
|  |      17buddyy      2021-08-19 19:02:12 +08:00 看标题我以为在 LSM-Tree 呢。 | 
|  |      18z740713651      2021-08-19 21:47:36 +08:00 |