【问题标题】:Matlab's arrayfun for uniform output of class objectsMatlab arrayfun 用于类对象的统一输出
【发布时间】:2012-06-09 12:05:04
【问题描述】:

我需要使用 arrayfun 构建一个 ID 类的对象数组:

% ID.m
classdef ID < handle
    properties
        id
    end
    methods
        function obj = ID(id)
            obj.id = id;
        end
    end
end

但是得到一个错误:

>> ids = 1:5;
>> s = arrayfun(@(id) ID(id), ids) 
??? Error using ==> arrayfun
ID output type is not currently implemented.

我可以循环构建它:

s = [];
for k = 1 : length(ids)
    s = cat(1, s, ID(ids(k)));
end

但是arrayfun 的这种用法有什么问题呢?

编辑(澄清问题):问题不是如何解决问题(有几种解决方案),而是为什么简单的语法s = arrayfun(@(id) ID(id), ids); 不起作用。谢谢。

【问题讨论】:

    标签: oop class matlab


    【解决方案1】:

    也许最简单的方法是使用 cellfun,或者通过设置 'UniformOutput' 选项强制 arrayfun 返回一个元胞数组。然后你可以将这个单元格数组转换为一个对象数组(与上面使用 cat 相同)。

    s = arrayfun(@(x) ID(x), ids, 'UniformOutput', false);
    s = [s{:}];
    

    【讨论】:

    • 谢谢,但它看起来像一个补丁,就像循环方法一样。我的问题是为什么arrayfun(@(id) ID(id), ids) 不起作用。是matlab的bug,还是用法错误?
    • 因为我有时会想念 python 功能来无休止地扩展命令,并且经常使用你的单元格到数组构造我经常声明一个匿名函数来一次性完成:dealcell = @(x)x{:};,然后可以使用喜欢s = [dealcell(arrayfun(...))];
    • 您需要s = reshape(s, size(ids)) 才能真正匹配arrayfun
    【解决方案2】:

    您要求arrayfun 做一些它不适合做的事情。

    The output from arrayfun must be:

    标量值(数字、逻辑、字符或结构)或单元格 数组。

    对象不计为任何标量类型,这就是为什么“解决方法”都涉及使用元胞数组作为输出的原因。要尝试的一件事是使用cell2mat 将输出转换为您想要的形式;它可以在一行中完成。 (不过我还没有测试过。)

    s = cell2mat(arrayfun(@(id) ID(id), ids,'UniformOutput',false));
    

    【讨论】:

    • 实际上 CELL2MAT 会失败并出现错误Cannot support cell arrays containing cell arrays or objects.
    • @Amro 啊,很有趣。感谢您指出这一点,就像我说我没有测试过一样。有没有办法将对象的句柄转换为向量?
    • 您可以创建对象数组(我发布了一个答案),只是不能使用 ARRAYFUN。事实上,ARRAYFUN 可以迭代对象数组(作为输入),只是不将它们作为输出返回(如您所指出的,必须返回单元格的标量)。你也可以像@robince 展示的那样做
    【解决方案3】:

    这就是我创建array of objects 的方式:

    s = ID.empty(0,5);
    for i=5:-1:1
        s(i) = ID(i);
    end
    

    提供不带参数的“默认构造函数”总是一个好主意,或者至少使用默认值:

    classdef ID < handle
        properties
            id
        end
        methods
            function obj = ID(id)
                if nargin<1, id = 0; end
                obj.id = id;
            end
        end
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-26
      • 1970-01-01
      • 1970-01-01
      • 2019-10-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多