有没有办法输入 if like:
var = (cond) ? true : false;
或者我们必须使用这种格式吗?
if (cond)
true
else
false
end
MatLab 没有三元运算符,或任何其他用于单行 if 语句的语法糖。但如果你的 if 语句真的很简单,你也可以把它写成一行:
if (cond); casetrue(); else; casefalse(); end
虽然不像三元运算符那么简单,但还是比用5行代码写出来要好。
嗯...没有人提到过这一点
fi = @(varargin)varargin{end-varargin{1}}
文档中的某处写着“终结”即将到来,因此这将更有利于未来
fi = @(varargin)varargin{length(varargin)-varargin{1}}
用途:
fi(input('Do you like Matlab ? '),'yes','no')
>> no
如果您需要内联案例,请参阅 Mathworks ...
如果您只需要 true 或 false,您可以按照
MatlabSorter
的建议进行操作。如果您想要真正的三级运算符(即 a = b ? c : d
),MATLAB 中没有。但是,使用此处提供的文件,您可以接近。
你可以做
var = 5 > 4;
这会将 var 设置为 true。只需用您需要的东西替换 5 > 4 即可。
MATLAB 没有条件表达式,但在某些情况下,您可以通过输入
var = cond*true_expr + (1-cond)*false_expr
来获得类似的效果。与 C 的条件表达式不同,这当然总是会计算 true_expr
和 false_expr
,并且如果 cond
恰好不是 0 或 1(注意:false
的行为类似于 0;true
的行为类似于 1)你会得到疯狂的结果。
与迄今为止提出的解决方案相比,以下解决方案具有两大优势:
if
/else
语句不同,它也可以在匿名函数中使用。function out = tern(cond, resTrue, resFalse)
if cond
res = resTrue;
else
res = resFalse;
end
out = res(); %<--- The trick!
实现延迟评估的技巧是
tern
中的最后一行评估所选结果。这样,您可以将匿名函数传递给tern
,并且只有选定的函数才会被调用。
例如当带有
fileName
的文件不存在时,可以调用以下命令而不会出现错误:
x = tern( isfile( fileName), @()load( fileName ), ones(10 ));
需要注意的是,当最后一行中
res
不是匿名函数而是不同的基本类型(例如 numeric、character、cell )时,res()
的计算结果为 res
本身。
总而言之,与 real 三元运算符唯一的区别在于,需要将
@()
添加到仅应有条件评估的参数中。
快速而优雅。我会简单地写 tern( a>b, a, b) 缺点是你必须到处复制粘贴,或者在目录中有额外的文件
function b = tern(cond, a, b)
if cond
b=a;
end
end
更换
c = (x ? a : b)
由
c = subsref({b; a}, substruct('{}', {x + 1}))
x 应该是布尔值或者 1 或 0。
true 或 1 将选择 a
false 或 0 将选择 b
这应该适用于单元格可以包含的所有内容,也可以在复杂的公式中使用!
@Leonid Beschastny 关于内联
if-else-end
语句是正确的,但如果必须,那么对于任何可以评估为布尔值的赋值值,可以使用快捷布尔运算符 ||
和 &&
:
(cond) && ((var=true_val)||1) || (var=false_val);
规则:
||
和 &&
,NOT |
或 &
(var=true_val)
后面必须跟
||1
,以防
true_val == false
(var1=true_val)
而
(var2=false_val)
)
true_val
和
false_val
可以是不同的类型,前提是每个都可以被评估为布尔值
cond && (func1(..)||1) || func2(...);
提供
func1
和
func2
返回一个布尔可测试值,不包含任何内容(但没有元胞数组!):
cond = what < ever;
n = getfield([23,42], {1+(what < ever)}) % for any 1x1-data
s = cell2mat(getfield({'no','yes'}, {1+(what < ever)})) % for nonuniform
它足够紧凑,不需要辅助函数
如果你想要一个
布尔值var = (cond) ? true : false;
你可以这样做:
var = cond;
如果您想要数字 var = (cond) ? value_if_true: value_if_false;
然后做:
var = cond*value_if_true + ~cond*value_if_false;
这都是利用matlab将true视为1,将false视为0。
因此,这就是为什么扩展的第一个语句确实是
var = cond*1+ ~cond*0;
如果您想要文字 var = (cond) ? text_if_true: text_if_false;
然后做:
[repmat(text_if_true,1,cond) repmat(text_if_false,1,~cond)];
不幸的是,您不能使用此方法将数值与文本混合,只需使用 if-else-end 语句编写即可。
0
)将矩阵值设置为
1
或
pi
时,我发现了这个问题。事实证明这很简单:
M > pi
当然,它比原来的问题不那么通用,但这个极端案例可能会对某人有所帮助。
vectorizedTernary = @(cond, resTrue, resFalse) cond.*resTrue + (1-cond).*resFalse
vectorizedTernary([0 1 1 0 0], 1:5, 5:-1:1) % ans = [5 2 3 2 1]
因为我使用了 1-cond
而不是
~cond
,你甚至可以将它用于非逻辑条件,例如概率:
vectorizedTernary([.2 .7 1], [.1 .2 .3], [0 1/3 2/3]) % ans = [.02 .24 .3]