How do you search for a number in a cell array containing different length arrays?

1 次查看(过去 30 天)
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.

采纳的回答

Dyuman Joshi
Dyuman Joshi 2023-11-28
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]}
in = 1×10 cell array
{[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))
idx = 1×7
2 4 5 6 7 9 10
  2 个评论
Dyuman Joshi
Dyuman Joshi 2023-11-28
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]};
in = 1×10 cell array
{[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
z = 1×10 logical array
0 1 0 1 1 1 1 0 1 1
out = vec(z)
out = 1×7
2 4 5 6 7 9 10
Dyuman Joshi
Dyuman Joshi 2023-11-28
Some timings -
%Generate random data
vec = randi([25 50], 1, 50000);
s = sum(vec)
s = 1873943
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())
ans = logical
1
fprintf('Time taken by for loop = %f seconds', timeit(F1))
Time taken by for loop = 0.008287 seconds
fprintf('Time taken by cellfun and any() = %f seconds', timeit(F2))
Time taken by cellfun and any() = 0.090079 seconds
fprintf('Time taken by cellfun and ismember() = %f seconds', timeit(F3))
Time taken by cellfun and ismember() = 0.128586 seconds
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

请先登录,再进行评论。

更多回答(2 个)

Voss
Voss 2023-11-28
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]}
C = 1×10 cell array
{[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
has_val = 1×10 logical array
0 1 0 1 1 1 1 0 1 1
result = find(has_val)
result = 1×7
2 4 5 6 7 9 10
Another way is to let cellfun do the loop for you:
has_val = cellfun(@(v)any(v == val),C)
has_val = 1×10 logical array
0 1 0 1 1 1 1 0 1 1
result = find(has_val)
result = 1×7
2 4 5 6 7 9 10

Fangjun Jiang
Fangjun Jiang 2023-11-28
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]}]
a = 1×10 cell array
{[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))
ans = 1×7
2 4 5 6 7 9 10

类别

Help CenterFile Exchange 中查找有关 Resizing and Reshaping Matrices 的更多信息

标签

产品


版本

R2023a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by