1

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}
StamDad
  • 135
  • 8
  • What language is this? This does not look like valid matlab syntax. – Tasos Papastylianou Nov 06 '17 at 15:39
  • they are not extractred from a code ..........I wrote them just for the question – StamDad Nov 06 '17 at 15:54
  • Shouldn't the first element of the output be an empty cell? – rahnema1 Nov 06 '17 at 18:02
  • Yes ..but then i mentionned that I add in every S{i} a content Oi ...so I add O1 in s{1}, O2 in s{2} ans so on – StamDad Nov 06 '17 at 18:33
  • @StamDad What went on with your comments to the answers is not normal for SO, as some might consider it a "chameleon problem" (i.e. where requirements change after the question was answered), lose patience, and leave (you're lucky that rahnema1 decided to answer ☺️). You should always use valid syntax in your question (where you specify the example inputs), to keep us from guessing what you mean; I had to guess twice - and got it wrong twice. Consider this a tip to help you get more/better/quicker/any answers. – Dev-iL Nov 07 '17 at 07:28
  • @Dev-iL......I understand ...Thank you – StamDad Nov 07 '17 at 16:33

2 Answers2

2

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:

Result2

Dev-iL
  • 23,742
  • 7
  • 57
  • 99
  • It's not exactly what I am looking for .....since my input data in`K` and `W` are not of type int .....But they are string of type `O1`,`O2`,... – StamDad Nov 06 '17 at 16:02
  • @StamDad Please see updated answer using `string` inputs (assuming that's what you meant). – Dev-iL Nov 06 '17 at 17:11
  • @Dev-iL......Thanks for the update, In my case I have `K` and `W` as a result of a previous partitions of my code . So idont need Input data , does this implies changes in your answer ? – StamDad Nov 06 '17 at 17:45
  • @StamDad notice the `if` at the beginning? It means that default values for `K` and `W` are only set if no inputs are provided. You can take this code, rename the function as you like, and pass it any `K` and `W` that fits the format you described. – Dev-iL Nov 06 '17 at 21:20
  • I got an error in `S{tmpW(ind2)} = union(S{tmpW(ind2)}, K{tmpW(ind2)});` ..`Second argument must be a string array, character vector, or cell array of character vectors.` – StamDad Nov 06 '17 at 21:40
1

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
  }
}
rahnema1
  • 15,264
  • 3
  • 15
  • 27
  • Very nice. But seems that in first output he wants `O1`, not null – Adiel Nov 06 '17 at 17:52
  • @Adiel I think the first element should be empty as I commented under the question. – rahnema1 Nov 06 '17 at 18:09
  • @rahnema1 Yes ..but then I mentionned in my question that I add in every S{i} a content Oi ...so I add O1 in s{1}, O2 in s{2} ans so on – – StamDad Nov 06 '17 at 18:34
  • @rahnema1...I got an error `result = accumarray(subs,vals,[],@(x){unique([cks{x}])})` ....`Dimensions of matrices being concatenated are not consistent.` .....I don't see any problem – StamDad Nov 06 '17 at 18:44
  • @rahnema1.....I edited the question ...I add the previous part of the code to see how the sets K and W were obtained – StamDad Nov 06 '17 at 19:39
  • @rahnema1....Stil got the error .....`.Dimensions of matrices being concatenated are not consistent`.....can't really understand where is the problem . – StamDad Nov 06 '17 at 20:27
  • @rahnema1...it works with the example inputs ......In my case the use of strings as node names is required . – StamDad Nov 06 '17 at 20:40
  • @rahnema1.....new error in `unique`.....`Cell array input must be a cell array of character vectors`. – StamDad Nov 06 '17 at 20:59
  • @rahnema1 ..http://www28.zippyshare.com/v/4YiVrQlS/file.html ....I renamed `K` into `cks ` – StamDad Nov 06 '17 at 21:27
  • @rahnema1....Yes I tried to remove it but got many errors , so I left it since the result is good – StamDad Nov 06 '17 at 22:43
  • @rahnema1.....it work's now ....it was the problem .....I just put the ` a=a+1` (not s=s+1 it was a taping mistake) inside the if condition. And replacing `cks{1,i}{a+1,1}=v{1,j}{1,1};` by `cks{1,i}{1,a+1}=v{1,j}{1,1}` – StamDad Nov 06 '17 at 22:59
  • @rahnema1 I don't get good results in the array `result` ...I get the following `result= {O1} {O2} {O3} {O4}` – StamDad Nov 06 '17 at 23:12
  • @rahnema1.. the problem as I told you is solved I just put the `a=a+1` (not s=s+1 it was a taping mistake) inside the if condition. And replace `cks{1,i}{a+1,1}=v{1,j}{1,1};` by `cks{1,i}{1,a+1}=v{1,j}{1,1}` – StamDad Nov 06 '17 at 23:29