用{}运算符包装函数是'UniformOutput'的有效替换,在cellfun中是false吗?

cod*_*tor 14 matlab function cell-array

cellfun用来将函数应用于单元格数组中的每个单元格.

我知道我必须设置'UniformOutput'false每当功能,使得该函数的输出被在一个单元阵列返回的包封返回非标量值.

以下面的单元格数组为例:

C1 = {[1 2 3], [4 5 6]};
Run Code Online (Sandbox Code Playgroud)

C1 有两个单元格,每个单元格包含三个元素的向量:

C1 =

  1×2 cell array

    [1×3 double]    [1×3 double]
Run Code Online (Sandbox Code Playgroud)

如果我想添加1到每个单元格中的内容,我可以定义该函数@(x) x + 1并使用cellfun如下方法应用它:

C2 = cellfun(@(x) x + 1, C1, 'UniformOutput', false);
Run Code Online (Sandbox Code Playgroud)

这非常有效,但请注意,我需要确保将'UniformOutput'其设置false为我之前解释过,否则将引发错误.

然而,看完之后此线程,我意识到,如果我用包功能单元阵列建设运营商{}这样的@(x) {x + 1}话,我并不需要设置'UniformOutput'false.

因此,以下命令将生成与C2不丢弃任何错误相同的结果:

C3 = cellfun(@(x) {x + 1}, C1);
Run Code Online (Sandbox Code Playgroud)

在代码布局方面,我更喜欢这种方法,因为它比前者更紧凑,更简洁,但我不确定这是否总是安全的.


因此我的问题是:

我是否可以始终用函数包装{}以避免设置'UniformOutput'false?或者有任何情况下这种替换不起作用?


我的研究:

help cellfun
Run Code Online (Sandbox Code Playgroud)

'UniformOutput'- 一个逻辑值,指示FUN在没有封装在单元阵列中的情况下是否可以返回输出.如果true(默认值),则FUN必须返回可以连接到数组中的标量值.如果true,输出必须是以下类型:numeric,logical,char,struct,cell.如果 false,cellfun返回一个单元格数组(或多个单元格数组),其中(I,J,...)单元格包含值FUN(C {I,J,...},...).当'UniformOutput'false时,输出可以是任何类型的.

以下片段是相关问题答案的一部分:

[...] cellfun负责解除引用操作,这是在循环时对单元的各个元素进行详细操作所必需的(即,{}...)[...]

gno*_*ice 15

有两种情况我可以想到使用单元格封装而不是附加参数...'UniformOutput', false)会导致问题,第一种情况比第二种情况更可能出现:

  • 捕获多个输出:有时您可能希望从正在应用的函数中捕获多个输出,例如调用unique单元数组的每个元素并获取其他索引参数.使用...'UniformOutput', false)我们可以轻松地这样做:

    >> C1 = {[1 2 3], [4 5 6]};
    >> [C2, index] = cellfun(@(x) unique(x), C1, 'UniformOutput', false)
    C2 =
      1×2 cell array
        [1×3 double]    [1×3 double]
    index =
      1×2 cell array
        [3×1 double]    [3×1 double]
    
    Run Code Online (Sandbox Code Playgroud)

    但是,使用单元封装时会失败:

    >> [C2, index] = cellfun(@(x) {unique(x)}, C1)
    Output argument "varargout{2}" (and maybe others) not assigned during call to
    "@(x){unique(x)}".
    
    Run Code Online (Sandbox Code Playgroud)
  • 没有输出的函数:我知道你在想什么:"但是如果它们没有产生输出,那么我不必担心收集非标量值!" 没错,但我想象的不寻常诚然场景进行评估的功能可能是一个额外的参数,比如作为参数传递功能手柄,所以你不知道先验多少产出,你会被处理.无论如何,这两种方法在这种情况下有所不同:

    >> C1 = {[1 2 3], [4 5 6]};
    >> cellfun(@(x) disp(x), C1, 'UniformOutput', false);
         1     2     3
         4     5     6
    
    >> cellfun(@(x) {disp(x)}, C1);
    Error using disp
    Too many output arguments.
    Error in @(x){disp(x)}
    
    Run Code Online (Sandbox Code Playgroud)

    可能不是你不必担心的事情,但我认为为了完整起见我会把它包括在内.