Arrays 如何获取这些数组并使用它们填充结构的字段?

Arrays 如何获取这些数组并使用它们填充结构的字段?,arrays,matlab,vector,struct,Arrays,Matlab,Vector,Struct,我有几个向量,想用它们填充结构数组中的字段。向量将只有两个长度中的一个-要么长度为N,要么长度为1。例如,如果N=3,我的向量可能如下所示: a = [0 5 7] b = [-2 6 8] c = 6 d = [11 12 13] e = 20 我希望结果是 my_structure(1).a = 0 my_structure(2).a = 5 my_structure(3).a = 7 my_structure(1).b = -2 my_structure(2).b = 6 my_str

我有几个向量,想用它们填充结构数组中的字段。向量将只有两个长度中的一个-要么长度为N,要么长度为1。例如,如果N=3,我的向量可能如下所示:

a = [0 5 7]
b = [-2 6 8]
c = 6
d = [11 12 13]
e = 20
我希望结果是

my_structure(1).a = 0
my_structure(2).a = 5
my_structure(3).a = 7

my_structure(1).b = -2
my_structure(2).b = 6
my_structure(3).b = 8

my_structure(1).c = 6
my_structure(2).c = 6
my_structure(3).c = 6

my_structure(1).d = 11
my_structure(2).d = 12
my_structure(3).d = 13

my_structure(1).e = 20
my_structure(2).e = 20
my_structure(3).e = 20
可以看到,对于最初只有length=1的向量,结构数组的每个元素都应该有相同的值

有没有一种简洁的方法可以实现这一点,而不必在每个元素上循环?它应该是可扩展的,这样我就可以添加更多的向量f,g,h,。。。如果需要的话


正如评论中所询问的,我不能简单地使用
my_结构.a=[0 5 7]
等,因为我需要能够将
my_结构(I)
传递给另一个函数,这要求每个字段只包含一个值(而不是数组)。

更新的答案

事实证明,您可以利用文档中的这一行:

如果任何值输入是非标度的单元格数组,则
s
的维度与该单元格数组相同

所以

这遵循了与下面原始答案相似的思维模式,但显然要简洁得多


原始答案

最简单的详细方法是从标量结构开始,并将其转换为结构数组。所以

N = 3;          % Each var has 1 or N elements

a = [0 5 7];    
b = [-2 6 8];
c = 6;

% Create an anonymous function to make all vars the correct size (1 or N)
pad = @(x) repmat(x, 1, N/numel(x));
% Create the scalar struct with padding
strctA = struct( 'a', pad(a), 'b', pad(b), 'c', pad(c) );
然后,可以使用循环将其转换为结构数组,该数组与变量名没有关联,因此更易于维护:

f = fieldnames(strctA);  % Get the field names, i.e. the original variable names
strctB = struct([]);     % Create an output struct. The [] input makes it a struct array
for iFn = 1:numel(f)     % Loop over the fields
    for n = 1:N          % Loop over the array elements
        strctB(n).(f{iFn}) = strctA.(f{iFn})(n); % Assign to new structure
    end
end

更新的答案

事实证明,您可以利用文档中的这一行:

如果任何值输入是非标度的单元格数组,则
s
的维度与该单元格数组相同

所以

这遵循了与下面原始答案相似的思维模式,但显然要简洁得多


原始答案

最简单的详细方法是从标量结构开始,并将其转换为结构数组。所以

N = 3;          % Each var has 1 or N elements

a = [0 5 7];    
b = [-2 6 8];
c = 6;

% Create an anonymous function to make all vars the correct size (1 or N)
pad = @(x) repmat(x, 1, N/numel(x));
% Create the scalar struct with padding
strctA = struct( 'a', pad(a), 'b', pad(b), 'c', pad(c) );
然后,可以使用循环将其转换为结构数组,该数组与变量名没有关联,因此更易于维护:

f = fieldnames(strctA);  % Get the field names, i.e. the original variable names
strctB = struct([]);     % Create an output struct. The [] input makes it a struct array
for iFn = 1:numel(f)     % Loop over the fields
    for n = 1:N          % Loop over the array elements
        strctB(n).(f{iFn}) = strctA.(f{iFn})(n); % Assign to new structure
    end
end

Wolfie的答案非常聪明,但您也可以使用更直接的解决方案,使用单个for循环:

N = 3;

a = [0 5 7]
b = [-2 6 8]
c = 6
d = [11 12 13]
e = 20

for i = 1:N
    my_structure(i).a = a(min(length(a), i))
    my_structure(i).b = b(min(length(b), i))
    my_structure(i).c = c(min(length(c), i))
    my_structure(i).d = d(min(length(d), i))
    my_structure(i).e = e(min(length(e), i))
end

这种方法的优点是代码更容易阅读。

Wolfie的答案非常聪明,但您也可以使用更直接的解决方案,使用单个for循环:

N = 3;

a = [0 5 7]
b = [-2 6 8]
c = 6
d = [11 12 13]
e = 20

for i = 1:N
    my_structure(i).a = a(min(length(a), i))
    my_structure(i).b = b(min(length(b), i))
    my_structure(i).c = c(min(length(c), i))
    my_structure(i).d = d(min(length(d), i))
    my_structure(i).e = e(min(length(e), i))
end

这种方法的优点是代码更容易阅读。

循环比像这样的手写更简洁。这是一个谬误,循环是缓慢的MATLAB,尤其是自从最新的JIT更新。为什么循环不符合您的目的?我不想这样手工编写-我写它只是为了显示我希望每个查询的结果。@Adrian我知道Matlab中有这些arrayfun()和structfun()函数,所以我怀疑有一种巧妙的方法可以使用它们来实现这一点。我一点也不担心循环速度慢。循环比像这样的手写要简洁得多。这是一个谬误,循环是缓慢的MATLAB,尤其是自从最新的JIT更新。为什么循环不符合您的目的?我不想这样手工编写-我写它只是为了显示我希望每个查询的结果。@Adrian我知道Matlab中有这些arrayfun()和structfun()函数,所以我怀疑有一种巧妙的方法可以使用它们来实现这一点。我一点也不担心循环太慢。谢谢你的回答。这实现了我想要的,但比我预期的要麻烦一些。我认为不使用arrayfun()或structfun()循环也可以完成,这样代码行就更少了,但您的解决方案甚至使用了两个嵌套循环。也许“最简单”和“简洁”是两个不同的东西。@Teeeee请看我的编辑,原来我很接近,但有一个更简单的答案。太棒了,很好的发现-我学到了一些东西!似乎即使在创建结构时省略了c中的pad()函数,它仍然可以工作。虽然我想最好还是把它保留下来。谢谢@Teeeee是的,标量将被复制/分发,但您必须将所有数组转换为单元格,否则它们也将被复制/分发。我编写了
pad
函数,这样它在这两种情况下都能工作,而不必关心输入变量的大小。如果您不想得到一般性的结果,也可以使用这个函数:
struct('a',num2cell(a),'b',num2cell(b),'c',c)
谢谢您的回答。这实现了我想要的,但比我预期的要麻烦一些。我认为不使用arrayfun()或structfun()循环也可以完成,这样代码行就更少了,但您的解决方案甚至使用了两个嵌套循环。也许“最简单”和“简洁”是两个不同的东西。@Teeeee请看我的编辑,原来我很接近,但有一个更简单的答案。太棒了,很好的发现-我学到了一些东西!似乎即使在创建结构时省略了c中的pad()函数,它仍然可以工作。虽然我想最好还是把它保留下来。谢谢@Teeeee是的,标量将被复制/分发,但您必须将所有数组转换为单元格,否则它们也将被复制/分发。我编写了
pad
函数,这样它在这两种情况下都能工作,而不必关心输入变量的大小。如果您不想得到一般性的结果,您可以使用它来获得相同的结果:
struct('a',num2cell(a),'b',num2cell(b),'c',c)