【问题标题】:How to add, subtract, etc. two structs element-by-element when they have the same fields当两个结构具有相同的字段时,如何逐个元素地相加、相减等
【发布时间】:2017-10-18 20:21:10
【问题描述】:

我有各种结构体,其中包含字段 W、P、E,其中包含数值。我想开发一种简洁的方法来添加和减去这些结构,而无需每次都在子函数中解包和重新打包(到目前为止,这一直是我的解决方案)

例如,给定:

S.W = 2
S.P = 3
S.E = 4

M.W = 20
M.P = 30
M.E = 40

我希望能够做到X = S + M 并最终得到:

X.W = 22
X.P = 33
X.E = 44

我目前的尝试是通过一个新类,如下所示:

classdef CV
    properties
        W
        P
        E
    end
    methods
        function r = plus(o1,o2)
            r = CV;
            r.E = o1.E + o2.E;
            r.P = o1.P + o2.P;
            r.W = o1.W + o2.W;
        end
    end
end

这允许执行 S + M 并以与输入相同的形式返回一个新变量。我一般不熟悉课程,想知道这是否是正确的形式。如果是这样,我可能会继续在methods 部分添加minustimes 的函数。但是,这似乎需要大量重复的代码,我觉得必须有一个更简单的解决方案。非常感谢任何建议。

【问题讨论】:

  • 你可以通过struct2array将struct转换成数组,进行计算,根据struct每个字段的维度将结果赋给struct
  • 这是一个好计划,但我担心没有办法检查所有结构是否具有相同的顺序(即,由于它们都在代码中的不同位置定义,我不想担心它们都是按 W、P、E 的顺序定义的,如果这是有道理的

标签: matlab class oop struct


【解决方案1】:

以下代码直接作用于结构,而不将它们嵌套在类中。假设两个输入结构具有相同的字段名称(在此示例中为 W、P 和 E),但是,它们的顺序可能是任意的(您在评论中提到这对您的应用程序很重要)。

function X = structplus(S, M)
fn = fieldnames(S);
for i = 1 : numel(fn)
  X.(fn{i}) = M.(fn{i}) + S.(fn{i});
end
end

所以定义

S.W = 2
S.P = 3
S.E = 4

M.E = 40
M.P = 30
M.W = 20

(注意M的倒序)和调用

X = structplus(S, M)

产生一个结构体,其字段名称与第一个参数一样排序:

X = 
  struct with fields:
    W: 22
    P: 33
    E: 44

【讨论】:

  • 谢谢,这是一个不错的优雅解决方案。你知道没有循环的方法吗?我发现如果我使用 cellfun 而不是循环,我无法获得结构输出
  • @teepee 那么,cell2struct(cellfun(@(n) M.(n)+S.(n), fn, 'UniformOutput', false), fn, 1) ?但cellfun 或多或少与for 循环相同
  • cellfun 在几乎所有重要的情况下都比显式循环
【解决方案2】:

要扩展 Le Phlaux 的答案,您可以为所需的二元运算符(例如 @plus@minus)提供函数句柄并递归处理子结构

function out = structBinaryFunc(in1, in2, func)
fn = fieldnames(in1);
for ii = 1:numel(fn)
    if isstruct(in1.(fn{ii}))
        out.(fn{ii}) = structBinaryFunc(in1.(fn{ii}), in2.(fn{ii}), func)
    else
        out.(fn{ii}) = func(in1.(fn{ii}), in2.(fn{ii}));
    end
end

对于您的示例,您可以调用X = structBinaryFunc(S, M, @plus);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-09
    • 2017-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-23
    • 1970-01-01
    相关资源
    最近更新 更多