ryh12
ryh12

Reputation: 367

Delete values between specific ranges of indices in an array

I have an array :

Z = [1 24 3 4 52 66 77 8 21 100 101 120 155];

I have another array:

deletevaluesatindex=[1 3; 6 7;10 12]

I want to delete the values in array Z at indices (1 to 3, 6 to 7, 10 to 12) represented in the array deletevaluesatindex

So the result of Z is:

Z=[4 52 8 21 155];

I tried to use the expression below, but it does not work:

X([deletevaluesatindex])=[]

Upvotes: 1

Views: 159

Answers (4)

rahnema1
rahnema1

Reputation: 15837

Edit: as in comments noted this solution only works in GNU Octave

with bsxfun this is possible:

Z=[1 24 3 4 52 66 77 8 21 100 101 120 155];
deletevaluesatindex = [1 3; 6 7;10 12];
idx = 1:size(deletevaluesatindex ,1);
idx_rm=bsxfun(@(A,B) (A(B):deletevaluesatindex (B,2))',deletevaluesatindex (:,1),idx);
Z(idx_rm(idx_rm ~= 0))=[]

Upvotes: 0

Robert Seifert
Robert Seifert

Reputation: 25232

Another solution using bsxfun and cumsum:

%// create index matrix
idx = bsxfun(@plus , deletevaluesatindex.', [0; 1])
%// create mask
mask = zeros(numel(Z),1);
mask(idx(:)) = (-1).^(0:numel(idx)-1)
%// extract unmasked elements
out = Z(~cumsum(mask))

out =    4    52     8    21   155

Upvotes: 1

Sardar Usama
Sardar Usama

Reputation: 19689

This will do it:

rdvi= size(deletevaluesatindex,1);   %finding rows of 'deletevaluesatindex'
temp = cell(1,rdvi);     %Pre-allocation

for i=1:rdvi
    %making a cell array of elements to be removed 
    temp(i)={deletevaluesatindex(i,1):deletevaluesatindex(i,2)};
end

temp = cell2mat(temp); %Now temp array contains the elements to be removed
Z(temp)=[]  % Removing the elements

Upvotes: 0

logan rakai
logan rakai

Reputation: 2557

If you control how deletevaluesatindex is generated, you can instead directly generate the ranges using MATLAB's colon operator and concatenate them together using

deletevaluesatindex=[1:3 6:7 10:12]

then use the expression you suggested

Z([deletevaluesatindex])=[]

If you have to use deletevaluesatindex as it is given, you can generate the concatenated range using a loop or something like this

lo = deletevaluseatindex(:,1)
up = deletevaluseatindex(:,2)
x = cumsum(accumarray(cumsum([1;up(:)-lo(:)+1]),[lo(:);0]-[0;up(:)]-1)+1);
deleteat = x(1:end-1)

Upvotes: 0

Related Questions