这篇文章是由following discussion触发的,关于单元格数组是否是“正常数组”,而且vectorizaton对单元格数组不起作用。
我想知道为什么在MATLAB中没有实现跟随矢量化语法,反对它的是什么:
>> {'hallo','matlab','world'} == 'matlab'
??? Undefined function or method 'eq' for input arguments of type 'cell'.
内部相当于
[{'hallo'},{'matlab'},{'world'}] == {'matlab'}
因为MATLAB知道何时投射,以下是作品:
[{'hallo','matlab'},'world']
单元格数组为an array of pointers。如果左侧和右侧都指向相同的对象,isequal('hallo','hallo')
按预期返回true,那么为什么MATLAB仍然不允许最顶层的示例?
我知道我可以使用strmatch
或cellfun
。
概要:
==
为eq
而不是isequal
(其他运算符为<
,lt
等。) eq
内置于数字类型,适用于所有其他类型(如字符串)MATLAB提供了对此(和其他)运算符进行重载的自由。myFun( myString )
或myFun( myCellOfStrings )
)也是可能的,您只需在myFun
内部实现它。函数sin(val)
和sin(array)
也不是通过巫术工作,而是因为这两种情况都是在内部实现的。答案 0 :(得分:6)
首先,==
不与isequal
相同。使用==
时调用的函数是eq
,并且每个函数的范围都不同。
例如,在eq(A,B)
中,如果B
是标量,则函数检查 A
的每个元素是否与B
相等并且返回逻辑向量。
eq([2,5,4,2],2)
ans =
1 0 0 1
但是,isequal(A,B)
会检查所有方面A
是否等于B
。换句话说,MATLAB无法区分A
和B
之间的区别。为上述示例执行此操作:
isequal([2,5,4,2],2)
ans =
0
我认为你真正打算在问题中提出的问题,但没有,是:
“为什么没有为单元格数组定义
==
?”
嗯,原因很简单:细胞不适合这种用途。当您开始考虑个别情况时,您可以很容易地看到如何为单元格实现这样的函数很快变得复杂。例如,考虑
{2,5,{4,2}}==2
您期望答案是什么?一个合理的猜测是
ans = {1,0,0}
这是公平的。但是,让我们说,我不同意。现在,我希望使用相等操作来遍历嵌套单元格并返回
ans = {1,0,{0,1}}
你能不同意这种解释吗?也许不是。它同样有效,在某些情况下,这就是你想要的行为。
这只是一个简单的例子。现在在单元格中添加嵌套单元格,不同类型等的混合,并考虑处理每个角落情况。对于开发人员来说,实现这样的功能很快就会变成一场噩梦,这些功能可以被所有人使用得令人满意。
因此,解决方案是重载函数,仅实现您所需的特定功能,以便在您的应用程序中使用。 MATLAB提供了一种方法,通过创建@cell
目录并定义eq.m
,以便按照 想要的方式使用单元格。 Ramashalanka在his answer中证明了这一点。
答案 1 :(得分:4)
对于MATLAB来说,有许多事情对他们选择不这样做是很自然的。也许他们不想考虑许多特殊情况(见下文)。你可以通过重载自己完成。如果您创建目录@cell
并将以下内容放在新函数eq.m
中:
function c = eq(a,b)
if iscell(b) && ~iscell(a)
c = eq(b,a);
else
c = cell(size(a));
for n = 1:numel(c)
if iscell(a) && iscell(b)
c{n} = isequal(a{n},b{n});
else
c{n} = isequal(a{n},b);
end
end
end
然后你可以做,例如:
>> {'hallo','matlab','world'} == 'matlab'
ans = [0] [1] [0]
>> {'hallo','matlab','world'} == {'a','matlab','b'}
ans = [0] [1] [0]
>> {'hallo','matlab','world'} == {'a','dd','matlab'}
ans = [0] [0] [0]
>> { 1, 2, 3 } == 2
ans = [0] [1] [0]
但是,即使我在我的简单函数中考虑过几个案例,但我还没有考虑很多事情(检查单元大小相同,检查多元素单元格与单例等等)。
我使用isequal
即使用eq
调用它(即==),因为它更好地处理{'hallo','matlab','world'} == 'matlab'
,但实际上我应该考虑更多的情况。
(编辑:我的功能略短,但效率较低)
答案 2 :(得分:1)
这不是字符串所特有的。即使以下情况也不起作用:
{ 1, 2, 3 } == 2
单元格数组不与“普通”数组相同:它们提供不同的语法,不同的语义,不同的功能,并且以不同的方式实现(一个额外的间接层)。
考虑单元数组上的==
是否在isequal
的基础上逐个元素地定义。所以,上面的例子没有问题。但是这个呢?
{ [1 0 1], [1 1 0] } == 1
在大多数情况下,由此产生的行为不会非常有用。那怎么样?
1 == { 1, 2, 3 }
你怎么定义这个? (我可以想到至少三种不同的解释。)
{ 1, 2, 3 } == { 4, 5, 6 }
那怎么样?
{ 1, 2, 3 } == { { 4, 5, 6 } }
还是这个?
{ 1, 2, 3 } == { 4; 5; 6 }
还是这个?
{ 1, 2, 3 } == { 4, 5 }
您可以添加各种特殊情况处理,但这会使语言更不一致,更复杂,更难以预测。
答案 3 :(得分:1)
出现此问题的原因是:单元格数组可以在不同的单元格中存储不同类型的变量。因此,无法为整个阵列很好地定义运算符==
。一个细胞甚至可能包含另一个细胞,这进一步加剧了这个问题。
想想{4,'4',4.0,{4,4,4}} == '4'
。应该是什么结果?每种类型都以不同的方式进行评估。