在单元格数组的单元格数组中查找字符串

时间:2015-02-22 13:28:37

标签: matlab cell-array

使用Matlab,假设我们有一个单元格数组的单元格。例如:

C = { {'hello' 'there' 'friend'}, {'do' 'say' 'hello'}, {'or' 'maybe' 'not'} }

我想找到C中包含字符串'hello'的所有单元格数组的索引。在这种情况下,我期望1和2,因为第一个单元阵列在第一个槽中有'hello'而第二个单元阵列在第三个槽中有它。

我想使用矩阵(一个简单的查找)会更容易一些,但出于教育目的,我也想学习使用单元格数组的过程。

非常感谢提前。

3 个答案:

答案 0 :(得分:5)

直接的方法

使用arrayfun -

out = find(arrayfun(@(n) any(strcmp(C{n},'hello')),1:numel(C)))

使用cellfun -

out = find(cellfun(@(x) any(strcmp(x,'hello')),C))

替代方法

您可以采用 cell array of cell arrays of strings 的输入翻译为 cell array of strings 的新方法,从而减少一个级别 "cell hierarchy" 。然后,它会执行strcmp,从而避免使用cellfunarrayfun,这可能会比以前列出的方法更快。请注意,从性能的角度来看,如果输入单元阵列的每个单元格中的单元格数量变化不大,这种方法会更有意义,因为该转换会导致填充空单元格的2D单元阵列< em>空位

这是实施 -

%// Convert cell array of cell ararys to a cell array of strings, i.e.
%// remove one level of "cell hierarchy"
lens = cellfun('length',C)
max_lens = max(lens) 
C1 = cell(max_lens,numel(C))
C1(bsxfun(@le,[1:max_lens]',lens)) = [C{:}]  %//'

%// Use strsmp without cellfun and this might speed it up
out = find(any(strcmp(C1,'hello'),1))

<强>解释

[1]将字符串的单元格数组的单元格数组转换为字符串的单元格数组:

C = { {'hello' 'there' 'friend'}, {'do' 'hello'}, {'or' 'maybe' 'not'} }

转换为

C1 = {
    'hello'     'do'       'or'   
    'there'     'hello'    'maybe'
    'friend'         []    'not'  }

[2]对于每一列,查找是否有any字符串hello并找到这些列IDs作为最终输出。

答案 1 :(得分:5)

这是一种使用正则表达式的方法,我认为它的效率远低于@Divakar的strcmp解决方案,但无论如何都可以提供信息。

regexp对单元格数组进行操作,但由于C是单元格数组的单元格数组,我们需要使用cellfun来获取单元格数组的逻辑单元格数组,之后我们再次使用cellfun来获取匹配的索引。实际上我可能会使用不必要的步骤,但我认为它更直观

代码:

clear
clc

C = { {'hello' 'there' 'friend'}, {'do' 'say' 'hello'}, {'or' 'maybe' 'not'} }

CheckWord = cellfun(@(x) regexp(x,'hello'),C,'uni',false);

此处CheckWord是包含0或1的单元格数组的单元格数组,具体取决于与字符串hello的匹配:

CheckWord = 

    {1x3 cell}    {1x3 cell}    {1x3 cell}

为了让事情更加清晰,让我们重新塑造CheckWord

CheckWord = reshape([CheckWord{:}],numel(C),[]).'

CheckWord = 

    [1]    []     []
     []    []    [1]
     []    []     []

由于CheckWord是一个单元格数组,我们可以使用cellfunfind来查找非空单元格,即与匹配项对应的单元格:

[row col] = find(~cellfun('isempty',CheckWord))

row =

     1
     2

col =

     1
     3

因此,包含单词“hello”的单元格是第1和第2。

希望有所帮助!

答案 2 :(得分:0)

假设内部单元格数组水平大小相同(如您的示例所示),并且您希望找到完全匹配字符串:

result = find(any(strcmp(vertcat(C{:}),'hello'), 2));

其工作原理如下:

  1. 将字符串C的单元格数组的单元格数组转换为字符串的2D单元格数组:vertcat(C{:})
  2. 将每个字符串与搜索到的字符串('hello')进行比较:strcmp(...,'hello')
  3. 查找找到匹配项的行的索引:find(any(..., 2))