请教一个最优逻辑方案,=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 3
if 包含 1,走 A
if 包含 2,走 B |
2
GM 2020-11-24 12:05:06 +08:00 11
这已经很好的逻辑了,简单易懂,你还想优化成什么样?
如果只是单纯想减少代码行数(然鹅可读性会变差)的话,考虑位运算: if x & 1 { A } if x & 2 { B } x == 3 的时候,两个判断都是 true,AB 都运行 |
3
Rekkles 2020-11-24 12:06:24 +08:00 4
|
4
gggxxxx 2020-11-24 12:06:45 +08:00 4
如果是我的话,换成 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 7
这不是史上最坑面试题 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 1
逻辑多的话可以用质数乘积,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
uselessVisitor 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 1
看眼神 😏😏😏😏😏😏😏😏
if(x!=2){ A() }else if(x!=1){ B() } |
17
xiangyuecn 2020-11-24 13:06:54 +08:00 1
#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 1
为什么你们包括 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 2
这就是一个很简单的问题,切勿过度设计过度猜疑,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 4
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 1
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
godwinma 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
|