I have a cell array {'W','L','D','D','W'}. I want to convert this into a {-1,0,1} array where 'W' is mapped to 1, 'D' to 0, and 'L' to -1.
Is there a quick way to do this without writing a loop?
You could use categorical arrays to do this in a single expression
double(categorical({'W','L','D','D','W'}, {'L', 'D', 'W'})) - 2
Or for MATLAB prior to R2013b, you can do two expressions:
[~, loc] = ismember({'W','L','D','D','W'}, {'L', 'D', 'W'});
result = loc - 2;
use strcmp :
A = {'W','L','D','D','W'};
B = strcmp (A,'W');
C = strcmp (A,'L') * -1;
B+C
ans =
1 -1 0 0 1
strcmp: B(strcmp(A, 'W')) = 1;@GameOfThrows's answer is good but it would not generalize well should your character-number mapping become more complex. Here is my solution:
Create a function that maps the characters the way you want
function n = mapChar(c)
if strcmp(c, 'W')
n = 1;
elseif strcmp(c, 'D')
n = 0;
elseif strcmp(c, 'L')
n = -1;
end
end
and then use cellfun to apply it over the cell array:
>> cellfun(@mapChar, {'W','L','D','D','W'})
ans =
1 -1 0 0 1
If you find that you need to use a different mapping, you just redefine your mapping.
Also, it all can be inlined (using part of the @GameOfThrows's approach):
>> cellfun(@(c)(strcmp(c, 'W') - strcmp(c, 'L')), {'W','L','D','D','W'})
ans =
1 -1 0 0 1
strcmp works over cell arrays already and you can use the logical return to index your result directly. e.g. B(strcmp(A, 'W')) = 1;strcmps. In that case it would be much easier to rewrite the one function rather than inventing a new way of how to do it with the whole arrays (which may become non-trivial). The inline version is just a bonus and, of course, is better performed with the whole arrays.switch statement would be more natural than if/else indoor first example.