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

3 ビュー (過去 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 Center および File ExchangeMatrices and Arrays についてさらに検索

タグ

製品


リリース

R2023a

Community Treasure Hunt

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

Start Hunting!

Translated by