Reputation: 135
I have two cell arrays of size [1X5]
K= {} {O1,O2,O3,O4} {O1,O3} {O1,O2,O3,O4} {O1,O2,O3,O4}
W= {O3}{O2}{O2,O3}{O2,O4}{O4}
I want to get as a result a cell array named S
of size [1X4] as follows :
I put the contents of K{i}
in every S{j}
where j
are the indices of the contents of W{i}
(for example the cell W{3}
has as content O2
and O3
so j=2,3
. I put the content of K{3}
in the cells S{2}
and S{3}
).
After that I add in every S{i}
a content Oi
and I eliminate redundancy in S
.
The expected result is the following :
S={O1}{O1,O2,O3,O4}{O1,O3}{O1,O2,O3,O4}
Upvotes: 1
Views: 83
Reputation: 15837
Here is a solution using accumarray and unique:
K= {{} ,{'O1','O2','O3','O4'} ,{'O1','O3'} ,{'O1','O2','O3','O4'} ,{'O1','O2','O3','O4'}};
W= {{'O3'},{'O2'},{'O2','O3'},{'O2','O4'},{'O4'}};
subs = sscanf(cell2mat([W{:}]),'O%d');
m = max(subs);
subs = [subs;(1:m).'];
vals = repelem(1:numel(W),cellfun(@numel,W));
vals = [vals numel(K)+1:numel(K)+m]
K = [K num2cell(cellstr(num2str((1:m).','O%d'))).'];
%If your data are string scalars use the following K
%K = [K num2cell(string(cellstr(num2str((1:m).','O%d')))).']
result = accumarray(subs,vals,[],@(x){unique([K{x}])})
result =
{
[1,1] =
{
[1,1] = O1
}
[2,1] =
{
[1,1] = O1
[1,2] = O2
[1,3] = O3
[1,4] = O4
}
[3,1] =
{
[1,1] = O1
[1,2] = O3
}
[4,1] =
{
[1,1] = O1
[1,2] = O2
[1,3] = O3
[1,4] = O4
}
}
Upvotes: 1
Reputation: 24169
You can use the union
function for this as well as several loops:
function S = q47140074(K,W)
if nargin < 2
% Input data:
K = {"", ("O"+(1:4).').', ("O"+[1;3]).', ("O"+(1:4).').', ("O"+(1:4).').'};
W = {"O3", "O2", ("O"+(2:3).').', ("O"+[2;4]).', "O4"};
end
% Preprocess data:
Wn = cellfun(@stripO,W,'UniformOutput',false);
% Preallocation:
S = num2cell(strings(1, max(cellfun(@max,Wn))));
% Computation:
for ind1 = 1:numel(Wn)
tmpW = Wn{ind1};
for ind2 = 1:numel(tmpW)
S{tmpW(ind2)} = union(S{tmpW(ind2)}, K{tmpW(ind2)});
end
end
for ind1 = 1:numel(S)
S{ind1} = setdiff(union(S{ind1},"O" + ind1),"");
end
end
function out = stripO(in)
out = str2double(strip(in,'left','O'));
end
Result:
Upvotes: 2