2012-11-06 14 views
17

Załóżmy, że mam komórkęjak przerobić komórkę na ciąg w Matlab

v = 'v' [576.5818] [3.0286] [576.9270] 

     'v' [576.5953] [3.1180] [576.8716] 

     'f' [  56] [ 58] [  52] 

     'f' [  56] [ 58] [  52] 

i chcę przekonwertować to do tablicy komórki przy użyciu ciąg formatu dla każdego elementu: ' %.5f'

Jak mogę Zrób to? Próbowałem następujące podejście, ale pojawia się błąd:

f1 = @(x) sprintf(' %.5f',x); 
cellfun(f1, num2cell(v),'UniformOutput', false) 

Otrzymuję błąd jako ???

Error using ==> sprintf

Function is not defined for 'cell' inputs.

Error in ==> @(x)sprintf(' %.5f',x)

Może ktoś mi pomóc z góry dzięki

Odpowiedz

21

String jest tablicą komórek

Cóż, nie do końca ... To jest matryca, ale czytaj dalej.

Chyba tablica komórek jest najbardziej mistycznym typem danych w MATLAB. Więc demystify to trochę ;-)

Załóżmy

fruits = {... 
    'banana',... 
    'apple',... 
    'orange'... 
} 

przede wszystkim całkowitej indeksacji nie jest potrzebna dla małych tablic. Znacznie lepiej jest używać konstrukcji podobnych do foreach. Rzeczywiście,

for index = 1:numel(fruits) 
    fruits{index} 
end 

jest równoważna

for fruit = fruits 
    fruit 
end 

prawda?

Cóż, niezupełnie. Pierwsza pętla tworzy łańcuchy, a druga komórki. Można to sprawdzić z

for index = 1:numel(fruits) 
    [isstr(fruits{index}) iscell(fruits{index})] 
end 

for fruit = fruits 
    [isstr(fruit) iscell(fruit)] 
end 

, tj [1 0] i [0 1].

Jeśli zauważysz różnicę, to musisz wiedzieć, co zrobić z następnym przykładem (w tym jest naprawdę związane z twoim pytaniem (!) Obiecuję!). Załóżmy, że starają się zrobić poziome konkatenacji w pętli:

for fruit = fruits 
    [fruit 'is a fruit'] 
end 

Dostaniesz

ans = 

    'banana' 'is a fruit' 

i tak dalej. Czemu? Podobno ten kod próbuje połączyć zagnieżdżoną tablicę komórek z łańcuchem znaków (tablicą komórek zawierającą macierz znaków, która tworzy ciąg taki jak "banan").Tak, poprawna odpowiedź jest

Wykorzystanie {:}

for fruit = fruits 
    [fruit{:} 'is a fruit'] 
end 

Magicznie to już produkuje oczekiwany 'banan to owoc', 'jabłko jest owocem' itp

wskazówki

kilka wskazówek:

  • Index wolne pętli działa ładnie z kodowanym jak w for fruit = [fieldnames][1](fruits)'
  • Powyższe prawda dla open source oktawy
  • banan nie tylko owoce, taksonomicznie to także zioło ;-) tak jak „banan” w MATLAB-ie jest zarówno ciągiem, jak i macierzą, tzn. assert (isstr ("banana") & & ismat ("banan") przechodzi, ale assert (iscell ('banana')) kończy się niepowodzeniem.
  • {:} jest równoważna cell2mat

PS

rozwiązanie do Twojego pytania może wyglądać następująco:

Biorąc

vcell = {... 
    'v' 576.5818 3.0286 576.9270; 
    'v' 576.5818 3.0286 576.9270  
} 

tajnych Indeksu mądry tylko typy numeryczne na ciągi

vcell(cellfun(@isnumeric, vcell)) = cellfun(@(x) sprintf('%.5f', x), vcell(cellfun(@isnumeric, vcell)), 'UniformOutput', false) 

powyżej wyjścia kodu

vcell =

'v' '576.58180' '3.02860' '576.92700' 
'v' '576.58180' '3.02860' '576.92700' 

, które mogą być łączone.

6

Załóżmy, że mamy komórkę następująco:

my_cell = {'Hello World'} 
class(my_cell) 
ans = 
cell 

możemy uzyskać ciąg z niego po prostu za pomocą operatora {:} na nim bezpośrednio.

class(my_cell{:}) 
    ans = 
    char 

pamiętać, że możemy użyć wyrażenia mycell{:} gdziekolwiek będziemy używać zwykłego łańcucha.

+0

sposób, aby przejść! Nigdy nie mów, że gravedigging nigdy nikomu nie pomógł. –

+0

wywoływanie zbędnej funkcji wywołanie 'sprintf' a hack - is lol –

2

Patrząc w pliku strjoin.m Znalazłem to:

string = [x{:}]; 
Powiązane problemy