Как заменить весь тип "string" на тип "char" в массиве ячеек? - PullRequest
0 голосов
/ 05 июля 2018

Контекст

В R2016b MATLAB представил новый тип string , в дополнение к обычному типу char . Пока все хорошо, но теперь у меня много проблем с набором инструментов JSONlab , который я использую.

Например, в R2015b loadjson возвращает ячейку 1x3 символ массив:

dd = loadjson('["Titi", "Toto", "Tata"]')

dd = 

    'Titi'    'Toto'    'Tata'

Но в R2018a loadjson возвращает 1x3 строку массив:

dd = loadjson('["Titi", "Toto", "Tata"]')

dd =

  1×3 cell array

    {["Titi"]}    {["Toto"]}    {["Tata"]}

Задача

Чтобы не менять код повсеместно, я бы исправил подпрограмму loadjson, чтобы заменить все типы string, которые он может вернуть, на типы char. Например, в следующем массиве ячеек:

test = { 'hello', "world", 0.3; 'how', 'are', "you"}

test =

  2×3 cell array

    {'hello'}    {["world"]}    {[0.3000]}
    {'how'  }    {'are'    }    {["you" ]}

Я хочу заменить все строки:

cellfun(@isstring, test)

ans =

  2×3 logical array

   0   1   0
   0   0   1

Есть ли способ, которым я могу сделать это быстро (т.е. без циклического прохождения всех элементов)?

PS: я знаю jsondecode и jsonencode для замены JSONLab в будущем, но пока я просто хочу быстро исправить патчи.

Ответы [ 4 ]

0 голосов
/ 05 июля 2018

Другое решение, , которое обсуждается в блоге UndocumentedMATLAB , - это "полу-документированная" функция controllib.internal.util.hString2Char. Вот как вы это используете:

test = { 'hello', "world", 0.3; 'how', 'are', "you"};
fixed_test = controllib.internal.util.hString2Char(test);

fixed_test =

  2×3 cell array

    {'hello'}    {'world'}    {[0.3000]}
    {'how'  }    {'are'  }    {'you'   }

Согласно сообщению в блоге, эта функция проходит рекурсивно через ввод, поэтому она работает даже в такой ситуации:

test = {"target1", struct('field',{123,'456',"789"})};
ft = controllib.internal.util.hString2Char(test);
{ft{2}.field}

ans =

  1×3 cell array

    {[123]}    {'456'}    {'789'}

Посмотрите на сообщение в блоге для некоторых предостережений.

0 голосов
/ 05 июля 2018

Вы можете использовать cellstr (что смущает, несмотря на то, что "str" ​​предлагает string ) для преобразования строк в символьные массивы без зацикливания или cellfun ... документы указывают следующее:

C = cellstr(A) преобразует A в массив ячеек векторов символов . Входной массив A может быть массивом символов, категориальным массивом или, начиная с R2016b, массивом строк.

test = {'hello', "world", 0.3; 'how', 'are', "you"}; % multi-type test cell array
ind = cellfun(@isstring, test);                      % indexing for string type items
test(ind) = cellstr(test(ind))                       % char-ify the strings!

A cellfun примечание к производительности для проверок класса:

В моих ответах и ​​ответах Луиса cellfun используется для определения того, какие элементы являются строками. Вы можете улучшить производительность cellfun для этой задачи ...

Согласно документам cellfun, есть некоторые опции массива символов, которые намного быстрее, чем их аналоги из дескриптора функции. Для индексации isstring, вероятно, намного быстрее запустить первый из них:

% rapid
ind = cellfun('isclass', test, 'string');
% akin to looping
ind = cellfun(@isstring, test);

У них одинаковый вывод, в простом тесте я вижу увеличение скорости в 4 раза:

% Create large test array of random strings
c = cell(100,1000);
c = cellfun(@(x) string(char(randi([65,122],1,10))), c, 'uni', 0);

% Create functions for benchmarking 
f=@()cellfun('isclass', c, 'string');
g=@()cellfun(@isstring,c);

% Timing on MATLAB R2017b
timeit( f ) % >> 0.017sec
timeit( g ) % >> 0.066sec 
0 голосов
/ 05 июля 2018

Начиная с MATLAB R2017b, вы можете использовать converttstringstochars :

[test{:}] = convertStringsToChars(test{:});
0 голосов
/ 05 июля 2018

Вы можете использовать cellfun, но он имеет более или менее ту же производительность, что и цикл:

test = {'hello', "world", 0.3; 'how', 'are', "you"};
ind = cellfun(@isstring, test);
test(ind) = cellfun(@char, test(ind), 'UniformOutput', false)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...