How do you search for a number in a cell array containing different length arrays?
2 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Keihan
am 28 Nov. 2023
Kommentiert: Dyuman Joshi
am 28 Nov. 2023
Is there a way to search for an element inside a cell array? I have the following cell array:
1×10 cell array
Columns 1 through 5
{[2 5 8 9]} {[1 2 4 5 7 10]} {[3 5 6 7 8 9 10]} {[1 2 3 5 8 9 10]} {[1 2 4 6 8 9]}
Columns 6 through 10
{[1 3 4 5 6 8]} {[1 2 4]} {[4 5 7 9]} {[1 2 5 7 10]} {[1 2 3 4 6 8]}
I'm trying to determine the index of the array that contains a number, such as 1 for example. So for this example 1 is in array elements 2, 4, 5, 6, 7,9 and 10.
0 Kommentare
Akzeptierte Antwort
Dyuman Joshi
am 28 Nov. 2023
in = {[2 5 8 9] [1 2 4 5 7 10] [3 5 6 7 8 9 10] [1 2 3 5 8 9 10] [1 2 4 6 8 9] [1 3 4 5 6 8] [1 2 4] [4 5 7 9] [1 2 5 7 10] [1 2 3 4 6 8]}
idx = find(cellfun(@(x) ismember(1, x), in))
2 Kommentare
Dyuman Joshi
am 28 Nov. 2023
Though, the fastest approach would be to use a for loop.
in = {[2 5 8 9] [1 2 4 5 7 10] [3 5 6 7 8 9 10] [1 2 3 5 8 9 10] [1 2 4 6 8 9] [1 3 4 5 6 8] [1 2 4] [4 5 7 9] [1 2 5 7 10] [1 2 3 4 6 8]};
vec = 1:numel(in);
%Lazy preallocation
z = vec~=0;
for k=vec
z(k) = any(in{k}==1);
end
z
out = vec(z)
Dyuman Joshi
am 28 Nov. 2023
Some timings -
%Generate random data
vec = randi([25 50], 1, 50000);
s = sum(vec)
arr = randi([1 100], 1, s);
in = mat2cell(arr, 1, vec);
f1 = @(x) funloop(x);
f2 = @(x) funcellany(x);
f3 = @(x) funcellismember(x);
F1 = @() f1(in);
F2 = @() f2(in);
F3 = @() f3(in);
%Check for equality first
isequal(F1(), F2(), F3())
fprintf('Time taken by for loop = %f seconds', timeit(F1))
fprintf('Time taken by cellfun and any() = %f seconds', timeit(F2))
fprintf('Time taken by cellfun and ismember() = %f seconds', timeit(F3))
As can be observed, for loop is atleast 10x faster than both of the cellfun() methods.
function out = funloop(in)
vec = 1:numel(in);
%Lazy preallocation
z = vec~=0;
for idx=vec
z(idx) = any(in{idx}==1);
end
out = vec(z);
end
function out = funcellany(in)
f=@(x) any(x==1);
out = find(cellfun(f,in));
end
function out = funcellismember(in)
out = find(cellfun(@(x) ismember(1, x), in));
end
Weitere Antworten (2)
Voss
am 28 Nov. 2023
C = {[2 5 8 9], [1 2 4 5 7 10], [3 5 6 7 8 9 10], [1 2 3 5 8 9 10], [1 2 4 6 8 9], [1 3 4 5 6 8], [1 2 4], [4 5 7 9], [1 2 5 7 10], [1 2 3 4 6 8]}
val = 1; % value to check for
One way is to write a for loop to check each element of C for whether its contents contain a 1 (or whatever value):
nC = numel(C);
has_val = false(1,nC);
for ii = 1:nC
has_val(ii) = any(C{ii} == val);
end
has_val
result = find(has_val)
Another way is to let cellfun do the loop for you:
has_val = cellfun(@(v)any(v == val),C)
result = find(has_val)
0 Kommentare
Fangjun Jiang
am 28 Nov. 2023
a=[{[2 5 8 9]} {[1 2 4 5 7 10]} {[3 5 6 7 8 9 10]} {[1 2 3 5 8 9 10]} {[1 2 4 6 8 9]},...
{[1 3 4 5 6 8]} {[1 2 4]} {[4 5 7 9]} {[1 2 5 7 10]} {[1 2 3 4 6 8]}]
f=@(x) any(x==1);
find(cellfun(f,a))
0 Kommentare
Siehe auch
Kategorien
Mehr zu Matrices and Arrays finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!