Merging adjacent cells in a cell array and applying rules to remove entries
4 ビュー (過去 30 日間)
古いコメントを表示
I have a cell array with cells of different sizes, for instance:
([-2, -1], [1, -2]; [1, -2], [2]; [1, -2, -1], [1, 2]). I would like to merge the cells in each row, so that I get:
([-2, -1, 1, -2]; [1, -2, 2]; [1, -2, -1, 1, 2]).
I would then like to perform an operation where, within each cell, if two consecutive numbers are equal in size but opposite in sign then they are both removed, e.g. [-2, -1, 1, -2] becomes [-2, -2], and [1, -2, -1, 1, 2] becomes [1, -2, 2], then becomes [1] (through a double application of this operation). So, my final cell array becomes: ([-2, -2]; [1]; [1]).
Any suggestions on how to accomplish these feats?
0 件のコメント
回答 (3 件)
Benjamin
2016 年 8 月 16 日
I'm sure there is a more efficient way, but this gets the job done:
a = {[-2, -1], [1, -2]; [1, -2], [2]; [1, -2, -1], [1, 2]};
output = cell(1);
% go thru each row of cell array
for iRow = 1:size(a,1)
% covert row to numerical array
temp = cell2mat(a(iRow,:));
flag = true;
while flag
Break = false;
% go thru each element
for iNum = 1:length(temp)
num = temp(iNum);
% see if there is a match
toRemove = find(temp == -num);
if ~isempty(toRemove)
% remove the matched elements
toRemove = [iNum,toRemove];
temp(toRemove) = [];
% need to get out of for loop since temp size has changed
Break = true;
break
end
end
if Break
continue
end
% store corrected array
output(end+1,1) = {temp};
flag = false;
end
end
output = output(2:end);
6 件のコメント
Guillaume
2016 年 8 月 16 日
Stephen, you must have missed my new comment which fixed the problem (and is essentially the same as your answer)
Bhavesh Bhatt
2016 年 8 月 16 日
I hope this is what you are looking for -
cell1 = {[-2,-1],[1, -2]; [1 -2], [2]; [1,-2, -1],[1,2]};
no_of_iterations = 2;
[r c] = size (cell1);
for i = 1:r
cell1{i,1} = [ cell1{i,1:c}] ; % Combine the elements
end
cell1(:,2:end) = []; % Delete the unwanted columns
for k = 1:no_of_iterations
c1 = cellfun('length',cell1);
for j = 1:r
i = 1;
while(i<c1(j))
if (cell1{j,1}(i).*(-1)) == (cell1{j,1}(i+1))
cell1{j,1}(i+1) = [];
cell1{j,1}(i) = [];
c1(j) = c1(j) - 2;
end
i = i + 1 ;
end
end
end
1 件のコメント
Stephen23
2016 年 8 月 16 日
編集済み: Stephen23
2016 年 8 月 16 日
This actually provides the requested output:
C = {[-2,-1], [1,-2]; [1,-2], [2]; [1,-2,-1], [1,2]};
D = cellfun(@(c)[c{:}],num2cell(C,2),'UniformOutput',false);
fun = @(v)abs(diff(sign(v)))==2 & diff(abs(v))==0;
for k = 1:numel(D)
idx = fun(D{k});
while any(idx)
D{k} = D{k}([true,~idx]&[~idx,true]);
idx = fun(D{k});
end
end
and the output:
>> D{:}
ans =
-2 -2
ans =
1
ans =
1
EDIT if speed is important, then without cellfun will be faster:
C = {[-2,-1], [1,-2]; [1,-2], [2]; [1,-2,-1], [1,2]};
D = cell(size(C,1),1);
fun = @(v)abs(diff(sign(v)))==2 & diff(abs(v))==0;
for k = 1:numel(D)
D{k} = [C{k,:}];
idx = fun(D{k});
while any(idx)
D{k} = D{k}([true,~idx]&[~idx,true]);
idx = fun(D{k});
end
end
0 件のコメント
参考
カテゴリ
Help Center および File Exchange で Loops and Conditional Statements についてさらに検索
製品
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!