请教一个最优逻辑方案,=1 走 A,=2 走 B, =3 走 AB 两个,怎么写比较好?
if x==1 { A }elseif x==2 { B }else { A B }
要求如上,有优雅的写法吗?
修正一下之前的Demo,想要的逻辑如下
if x==1 { A }elseif x==2 { B }elseif x==3 { A B }
![]() | 1 CommandZi 2020-11-24 12:04:35 +08:00 ![]() if 包含 1,走 A if 包含 2,走 B |
2 GM 2020-11-24 12:05:06 +08:00 ![]() 这已经很好的逻辑了,简单易懂,你还想优化成什么样? 如果只是单纯想减少代码行数(然鹅可读性会变差)的话,考虑位运算: if x & 1 { A } if x & 2 { B } x == 3 的时候,两个判断都是 true,AB 都运行 |
![]() | 3 Rekkles 2020-11-24 12:06:24 +08:00 ![]() |
4 gggxxxx 2020-11-24 12:06:45 +08:00 ![]() 如果是我的话,换成 switch 就行了。我不会纠结什么最优解,语意明确最重要。 |
![]() | 5 chogath 2020-11-24 12:10:29 +08:00 (function (x) { const dict = { 1: 'A', 2: 'B', 3: 'AB' }; return dict[x] } )(3) |
6 swikis 2020-11-24 12:12:40 +08:00 via iPhone 策略模式 |
![]() | 7 secondwtq 2020-11-24 12:13:19 +08:00 via iPhone ![]() 这不是史上最坑面试题 fizzbuzz 么…… 别问了,99.5%的程序员都不会的 |
8 jadehare 2020-11-24 12:14:34 +08:00 if(n / 2 >= 1) B; if(n%2 == 1) A; |
![]() | 9 icql 2020-11-24 12:25:27 +08:00 ![]() 逻辑多的话可以用质数乘积,A=2,B=3,C=5,x%A==0 执行 A,x%B==0 执行 B,x%C==0 执行 C,例如 x=6,就会执行 AB,x=30 就会执行 ABC,对外用枚举封装需要的逻辑组合的质数乘积 |
![]() | 10 Mutoo 2020-11-24 12:28:01 +08:00 A = 1 B = 2 C = 4 D = 8 Input = A | B // equals 3 if (Input & A) /* DO A */ if (Input & B) /* DO B */ if (Input & C) /* DO C */ if (Input & D) /* DO D */ 将 ABCD 编码成 2 的 n 次方,然后可以用 | 运算来组合配置项,用 & 运算来检查配置项, 这在 C 编程中很常用,例如: if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) != 0) { |
11 zm8m93Q1e5otOC69 2020-11-24 12:31:30 +08:00 via Android @Rekkles 过分了 |
12 across 2020-11-24 12:46:23 +08:00 上面那个位运算 if 的已经被占了,这个应该是最简洁明了的。 从 C 升级到 C++折腾版后,还有一个 Map<fnPtr,fnPtr>(Condition,Action),就是判断条件比较复杂时,挨个遍历 map 执行 condition,执行 action 按简单数值比较场景来说就不用了。 |
13 mooczz 2020-11-24 12:52:00 +08:00 via iPhone 逻辑与运算,刚好是 1 10 11 |
![]() | 14 geelaw 2020-11-24 12:59:09 +08:00 via iPhone 这取决于 1 、2 、3 的含义:如果这是一个位映射枚举,则用位运算 #2 是自然的解法;如果这不具有位映射枚举的含义,则楼主本来的写法自然。 自然的表达即“本来是什么意思就表达什么”。 |
![]() | 15 zjsxwc 2020-11-24 13:01:47 +08:00 $f = [ 1 => (){A();}, 2 => (){B();}, 3 => (){A();B();}, ]; $f[x](); |
![]() | 16 xiangyuecn 2020-11-24 13:06:10 +08:00 ![]() 看眼神 if(x!=2){ A() }else if(x!=1){ B() } |
![]() | 17 xiangyuecn 2020-11-24 13:06:54 +08:00 ![]() #16 应该不要 else if(x!=2){ A() } if(x!=1){ B() } |
![]() | 18 sunshinev OP @xiangyuecn 厉害啊,这脑回路 |
![]() | 22 DoubleShut 2020-11-24 13:21:41 +08:00 花里胡哨的,switch case 不行吗? |
![]() | 24 yaoweilei 2020-11-24 13:23:09 +08:00 go="A" if x==1 else "B" if x==2 else "C" |
25 Lemeng 2020-11-24 13:23:26 +08:00 文明人讲究优雅。 |
![]() | 26 leo108 2020-11-24 13:45:09 +08:00 switch (x) { case 3: // no break case 1: A; if (x === 1) { break; } case 2: B; break; } |
![]() | 27 antiquezzz 2020-11-24 13:56:50 +08:00 兄弟不会真的以为会写 FizzBuzz 很难得吧 |
![]() | 28 rainman777 2020-11-24 14:05:06 +08:00 ``` if (n & 0x01) fun_a(); if (n & 0x02) fun_b(); ``` |
![]() | 29 hws8033856 2020-11-24 14:15:07 +08:00 ![]() 为什么你们包括 LZ 都不按题目要求来? 不是=3 才执行 AB 么? 你们怎么都是除=1 和=2 以外的其他值都执行 AB ? |
30 Jooooooooo 2020-11-24 14:25:39 +08:00 最优的解法最容易看懂 |
![]() | 31 shenjies88 2020-11-24 14:32:48 +08:00 ![]() 这就是一个很简单的问题,切勿过度设计过度猜疑,if 或者 switch 即可 |
![]() | 32 marcong95 2020-11-24 14:48:36 +08:00 @hws8033856 #29 因为楼主的提供的样例里面就是 else { AB },那么问题来了,到底是 else AB 呢,还是=3 AB 呢,如果 x = 4 呢,楼主这题似乎已经有这个坑了 若 x 属于 { 1, 2, 3 },那位运算+短路求值看着还挺舒服 x & 1 && A() x & 2 && B() |
![]() | 33 northisland 2020-11-24 15:00:33 +08:00 一条搞定,但是很鬼畜,可读性不高。 ``` #include <ciso646> x&0x01 and A() or y&0x02 and B(); ``` 我宁愿展开: if (x==1) A() else if (x==2) B() else if (x==3) {A(); B();} |
![]() | 34 sunshinev OP 其实看到很多位运算方案,但是总觉得位运算起来很短,但是不是很容易理解~可能我还没找到窍门 |
![]() | 35 lloydsheng 2020-11-24 15:03:37 +08:00 如果没有性能问题,写的越清晰易懂越好 |
![]() | 36 terence4444 2020-11-24 15:04:36 +08:00 via iPhone 按 bit 开关判断即可 1A 2B 4C 8D 16F |
37 zlowly 2020-11-24 15:05:52 +08:00 那要看不同场景下优雅是怎么定义了。如果这是在一个追求性能的的核心代码 /引擎之类的里,肯定是有优化空间;如果只是个普通代码片段,楼主本身的代码就没什么问题;如果是在业务逻辑代码里,可考虑的地方就多了,常见的是日后考虑调整或扩展=4=5 之类情况,有可能是更复杂的 ABCBA 执行情况等等,为了可读性和可维护性这时候上模式设计都是可以的。 |
![]() | 38 hws8033856 2020-11-24 15:06:37 +08:00 @marcong95 所以我才说“包括 LZ” 都不按题目要求来 只论代码长短,应该没有比你这个更短的了 不过我始终认为所谓代码的优雅,应该更多要看重代码的可读性 你这里用逻辑运算符来替代分支,就是很严重的破坏可读性,不优雅 |
39 lx0758 2020-11-24 15:16:02 +08:00 位运算 |
40 artikle 2020-11-24 15:22:48 +08:00 ![]() if(x==1||x==3) A(); if(x==2||x==3) B(); |
42 vitoliu 2020-11-24 15:27:55 +08:00 用模式来做处理不是更好吗,推荐组合模式 |
![]() | 43 Kamiyu0087 2020-11-24 15:30:12 +08:00 ![]() when (x) { 1 -> A() 2 -> B() 3 -> { A() B() } } |
![]() | 44 marcong95 2020-11-24 15:41:20 +08:00 |
![]() | 45 hst001 2020-11-24 16:11:38 +08:00 你这问题,还刚好 123,就是设计考位运算的题吧 |
46 cambria 2020-11-24 16:12:40 +08:00 如果 x 取值只有 1,2,3 的话可以这么写( python): if (x % 2): A() if (x // 2): B() |
![]() | 47 supuwoerc 2020-11-24 17:18:17 +08:00 x==1?a:x==2?b:x==3?a&b:null; |
48 wnpllrzodiac 2020-11-24 17:31:47 +08:00 via Android 位操作?最低位表示 a 第二位表示 b. |
![]() | 49 imn1 2020-11-24 18:10:45 +08:00 x&1: A (x>>1)&1: B |
50 vhysug01 2020-11-24 18:14:02 +08:00 via iPhone 查表 |
51 skrskrskrskr 2020-11-24 18:16:31 +08:00 这一看就是工作不饱和 |
52 xumng123 2020-11-24 18:52:14 +08:00 via iPhone 查表即可 |
![]() | 53 ychost 2020-11-24 19:10:18 +08:00 Map funcMap = {1:A,2:B,3:A&B} |
![]() | 54 lovecy 2020-11-24 19:23:23 +08:00 let funcMap = new Map([[1, func A], [2, func B], [3, func C]]); funcMap.get(x)(); |
55 manymobi 2020-11-24 19:47:43 +08:00 我觉得 你在考虑思想, 上面这个问题太局限了, 可以看看 spirng HttpMessageConverter |
56 woahishui 2020-11-24 20:02:35 +08:00 via Android 策略模式加命令模式 |
57 nocrush 2020-11-24 20:28:36 +08:00 搞一个 map |
58 phpIsNumberOne 2020-11-24 20:44:01 +08:00 goto |
59 jinliming2 2020-11-24 20:52:27 +08:00 支持 Excel 吗? =SWITCH(A1, 1, "A", 2, "B", 3, "AB", "other") |
![]() | 60 yeyu1989 2020-11-24 21:33:30 +08:00 decode(x,1,A,2,B,3,AB) |
61 bbxiong 2020-11-24 23:23:37 +08:00 if x == 1 then a elseif x == 2 then b elseif x == 3 then a b end 我觉得越简单,用简单清晰的代码写出来就行了 |
62 iceheart 2020-11-25 08:48:27 +08:00 via Android 老老实实写,别搞花样 |
63 dragonbuf 2020-11-25 09:45:04 +08:00 1 A B C 的逻辑封装 helper ALogicHelper{} BLoginHelper{} CLoginHelper{} 2 根据用途挑选 helper 组成 handler 3 handler 注册进 factory DemoFatoryHandlerRegistry{1:AHandler, 2:Bhandler,3ABHandler} 4 根据 id 获得 handler 接口 DemoFactory::fromId(int id)->getHandler():HandlerInterface 5 根据接口处理数据 HandlerInterface->dosomething(); |
![]() | 64 someonedeng 2020-11-25 09:53:42 +08:00 一通下来,还是最朴素的最优雅。没有性能问题就不搞花的了,代码是给人看的 |
65 diegozhu 2020-11-25 09:59:53 +08:00 1. 转 map: {1: "A", 2: "B", 3: "AB"}[X] 2. |
67 13670515509 2020-11-25 10:49:57 +08:00 js let obj = { 1: [A], 2: [B], 3: [A, B] } obj[x] && Array.isArray(obj[x]) && obj[x].forEach(fn => {typeof fn === 'function' && fn()}) |
![]() | 68 windsound 2020-11-25 11:11:43 +08:00 @xiangyuecn 卧槽,优秀。 |
69 slipper 2020-11-25 11:51:38 +08:00 如果以后还会加其他的判断情况,考虑扩展性,可以使用 visitor pattern,如果没有,直接写就很好了。 |
![]() | 70 shm7 2020-11-25 13:21:46 +08:00 其他值怎么处理,不考虑吗? |
71 crazyhorse 2020-11-25 13:23:35 +08:00 function run(x) { const runner = [{ x: [1,2], }] if(runA.indexOf) } |
72 crazyhorse 2020-11-25 13:32:08 +08:00 //有后续扩展(更多条件和要执行的方法) function a() {console.log('a')} function b() {console.log('a')} function run(x) { const runners = [{ x: [1,2], func: a, },{ x: [2,3], func: b, }] runners.forEach((runner) => { if(runner.x.indexOf(x) !== -1) runner['func'](); }) } //固定 ab 但是条件有后续扩展 function run(x) { const runA = [1,2]; const runB = [2,3]; if(runA.indexOf(x) !== -1) a(); if(runB.indexOf(x) !== -1) a(); } |
![]() | 73 raaaaaar 2020-11-25 15:54:43 +08:00 via Android 分支或者查表,看应用场景吧。 |
74 donaldsu 2020-11-25 16:19:36 +08:00 想到两个,不过都已经被占了 1 、mask 位运算 2 、switch case |
![]() | 75 xiaoliu926 2020-11-25 19:26:42 +08:00 @Kamiyu0087 kotlin 大法好 |
![]() | 76 RickyC 2020-11-25 23:03:33 +08:00 果然你们后端都是逻辑狂人 |
![]() | 77 SmiteChow 2020-11-26 10:38:34 +08:00 你提到的才是最优雅的,其他都是 tricky |
![]() | 78 northisland 2020-12-06 16:28:26 +08:00 via Android x&0x01 and A() and false or y&0x02 and B() and false |