list the result of the index values in ranges

Asked by Nasser Ramsis

Nasser Ramsis (view profile)

on 22 Oct 2017
Latest activity Commented on by Nasser Ramsis

Nasser Ramsis (view profile)

on 23 Oct 2017
Accepted Answer by Jos (10584)

Jos (10584) (view profile)

Hello,
I have an array that is populated with the values 1,2 or 3.
a = [1 1 2 2 3 3 2 2 1 1];
and I want to list the ranges of each value. The find function retrieves the index to each number which is great.
[col1] = find(a==1)
[col2] = find(a==2)
[col3] = find(a==3)
but is there a function or some logic i can use to list col1, col2, and col3 as ranges? as in col1 = 1-2 and 9-10 and col2 = 3-4 and 7-8 etc etc.
I appreciate any ideas or help.
Thank you in advance!

Jos (10584)

Jos (10584) (view profile)

on 22 Oct 2017
You might want to search for run length encoding.

Tags

Answer by Jos (10584)

Jos (10584) (view profile)

on 22 Oct 2017

A = [1 1 2 2 3 3 2 2 1 1];
X = arrayfun(@(k) find(A==k),1:3,'un',0) ;
Y = cellfun(@(v) [v([true diff(v) > 1]) ; v([diff(v) > 1 true])]', X,'un',0) ;
% Y{k} contains the start indices (1st column) and end indices (2nd column) for a sequence of the value k in A

Nasser Ramsis

Nasser Ramsis (view profile)

on 23 Oct 2017
Thank you.
This is working great in 1 of my functions but this other function is giving me this message:
Index exceeds matrix dimensions.
Error in @(v)[v([true,diff(v)>1]);v([diff(v)>1,true])]'
Error in test (line 60) Y = cellfun(@(v) [v([true diff(v) > 1]) ; v([diff(v) > 1 true])]', X,'un',0) ;
Any ideas? do you want to see the entire code?

Answer by Andrei Bobrov

Andrei Bobrov (view profile)

on 22 Oct 2017
Edited by Andrei Bobrov

Andrei Bobrov (view profile)

on 22 Oct 2017

a = [1 1 2 2 3 3 3 2 2 1 1];
l = diff([0,a(:)'])~=0;
b = [strfind(l,[1 0]);strfind([l,1],[0 1])]';
out = accumarray(a(l)',1:size(b,1),[],@(x){sortrows(b(x,:))});