1

I have a function that takes variadic arguments. These arguments are parameter-value pairs, so varargin is a cell array in which every odd-indexed element is a string (the parameter), but the even-indexed elements can be a string, number, or cell array of strings. I want to find the index of a particular string in varargin. I have a working solution, but it uses arrayfun twice; is there a cleaner/faster/more effective way of find a string in such a cell array? The resulting index will be used to remove that element and the following one from varargin. I would like to minimize creation of new variables.

str_to_find = 'paramX'
finds = arrayfun(@(i) strfind(varargin{i},str_to_find), 1:length(varargin), 'UniformOutput', 0);
finds2 = arrayfun(@(i) ~iscell(finds{i}) && ~isempty(finds{i}), 1:length(finds));
index = find(finds2==1);

varargin(index)=[];
varargin(index)=[];

Given varargin is {'paramA', 'valueA', 'paramB', 9, 'paramX', {'z','x','c'}, then finds is [] [] [] [] [1] {1x3 cell}, finds2 is 0 0 0 0 1 0, and index is 5. So, my solution does what I need, but it just seems ugly. I would just use finds2 (i.e., not create index) to delete that element from varargin, but I also need to remove the one after it.

knowah
  • 110
  • 4
  • 11

2 Answers2

3

You can use the built-in function strcmp which should be fairly fast:

idx  = strcmp(str_to_find, varargin);

and that will give you an index to all cell elements that are strings matching the target.

Then, for pruning those elements, you can use

varargin( or(idx, [0 idx(1:end-1)]) ) = [];

assuming that idx is a row array.

Finally, you may also want to run some format checks to make sure that the user has not entered argument-pairs in the wrong order (or with an argument name that matches the parameter name) otherwise this kind of code will behave strangely.

cjh
  • 866
  • 4
  • 16
  • It worked great except I got `Subscript indices must either be real positive integers or logicals.` since the addition converted `idx` to doubles. I changed the indexing to `logical(idx+[0 idx(1:end-1)])` and it works. – knowah Aug 14 '12 at 18:45
  • Glad it worked for you, @knowah! Thanks for the note on addition... I edited my answer to use the `or` operator instead. – cjh Aug 14 '12 at 18:57
0

What about trying this:

index  = find(strcmp(str_to_find, varargin));

This should give the index of 'parameter' and adding one to it will get the index of its 'value'