How do you search for a number in a cell array containing different length arrays?
1 visualizzazione (ultimi 30 giorni)
Mostra commenti meno recenti
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 Commenti
Risposta accettata
Dyuman Joshi
il 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 Commenti
Dyuman Joshi
il 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
il 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
Più risposte (2)
Voss
il 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 Commenti
Fangjun Jiang
il 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 Commenti
Vedere anche
Categorie
Scopri di più su Resizing and Reshaping Matrices in Help Center e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!