如何在MATLAB中连接作为单元数组一部分的单元数组?

7

我有一个名为allData的单元数组,它是Nx1。每个单元格都包含一个结构体,其中有一个names属性(名称是自定义对象,但如果您愿意,可以将其视为字符串的单元数组)。我想创建一个单一的单元数组,其中包含所有名称。例如,如果N=3,allData是一个3x1的单元数组,则以下内容可以实现我的目标:

A = allData{1};
B = allData{2};
C = allData{3};

allNames = [A.names B.names C.names];

这种方法的问题在于N很大并且取决于输入,所以我希望有一种聪明的方法可以使用cellfun来完成这个任务,但是我尝试的所有方法都失败了(例如,这样做不起作用:allNames = [cellfun(@(x) {x.names}, allData)];)。
更新:感谢提供的解决方案,我可以将所有内容放入一个单元数组中,每个单元都包含一个单元数组。我的目标是将它们连接起来。更或者说,我所拥有的东西是:
{A.names B.names C.names} 

而我所希望却似乎无法得到的是

{A.names{1} A.names{2} ... A.names{end} B.names{1} ... B.names{end} ...}
解决方案: 我需要每个答案的一部分,所以这是对我有用的解决方案:
来自Andrew LazarusallNames = arrayfun(@(x) x.name, [allData{:}], 'UniformOutput', false); 然后,来自gnoviceallNames = vertcat(allNames{:}); 感谢两位!

这些结构体是标量(即1乘1),还是可以是结构体数组 - gnovice
2个回答

4

如果names属性总是返回字符串单元数组,并且如果您的结构体都是标量(即1x1结构体数组),那么以下解决方案将使用CELLFUNCHARCELLSTR为您提供一个包含所有名称的Nx1单元数组allNames

allNames = cellfun(@(x) {char(x.names)},allData);
allNames = cellstr(char(allNames{:}));

以下是一个例子,其中allData包含三个不同的结构:

>> allData{1} = struct('names',{{'hello'}},'junk',1:3);
>> allData{2} = struct('names',{{'hi' 'yo' 'hey' 'whassup'}});
>> allData{3} = struct('names',{{'howdy';'aloha'}},'junk',4);
>> allNames = cellfun(@(x) {char(x.names)},allData);
>> allNames = cellstr(char(allNames{:}))

allNames = 

    'hello'
    'hi'
    'yo'
    'hey'
    'whassup'
    'howdy'
    'aloha'

编辑:

如果names属性返回的是一个单元数组,其中包含的是对象而不是字符串,你可以尝试以下解决方案。首先使用reshape函数将每个单元数组重塑为M×1的单元数组,然后使用vertcat函数将它们全部垂直连接成一个N×1的对象单元数组:

allNames = cellfun(@(x) {reshape(x.names,[],1)},allData);
allNames = vertcat(allNames{:});

或者,如果你想最终得到一个1-by-N的对象单元数组,可以这样做:

allNames = cellfun(@(x) {reshape(x.names,1,[])},allData);
allNames = [allNames{:}];

这对于它们是字符串的单元格数组来说非常好,但不幸的是我误导了你。它们是自定义对象的单元格数组。尽管如此,我可能仍然能够从这种方法中获得一些收益。谢谢! - PengOne
1
@PengOne:这个故事的寓意是“记得在你的问题中提供样本数据”。 - Richie Cotton
@Richie Cotton:该对象定义在多个文件和许多行中,因此它只会混淆问题,而问题的核心很简单:如何连接作为单元格数组的单元格本身的单元格数组? - PengOne
@PengOne:我更新了我的答案,更普遍地处理对象而不是字符串。 - gnovice
JessumCrow!vertcat函数正常工作了(一旦我正确地转置了)!谢谢你的帮助。对于我的例子,我不需要重新塑形,但是请在您的解决方案中保留它,以防其他人在这个问题上碰壁。 - PengOne

1

试试这个

 allNames = arrayfun(@(x) x.name, [allData{:}], 'UniformOutput', false)

省略UniformOutput可变参数以进行直接连接,这将产生单元格输出。

如果单元数组的元素可以水平串联成结构体数组,那么操作[allData{:}]才会有效,这意味着一开始使用单元数组并没有真正的原因。 - gnovice
@PengOne:注意[方括号]。但我会尝试更通用的解决方案。 - Andrew Lazarus
尝试了这个...结果是一个1x3的单元格数组,每个单元格包含一个我真希望能够找到一种方法将它们连接起来的单元格数组! - PengOne
@PengOne,不太确定您的意思,但有一个可能性:将UniformOutput更改为true,即可获得数组输出。这本来就是默认设置。您可能需要转置输出以获取连接的单个字符串。 - Andrew Lazarus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接