2012-04-02 1 views
1

Есть ли способ исключить пустые строки из динамического массива, полученного в результате функции SplitString (Delphi XE, StrUtils), без необходимости проходить через массив?Устранение пустых строк с помощью SplitString

Если нет, может ли кто-нибудь предложить наиболее эффективный способ сделать это? Сейчас я делаю это так:

function SplitStringNoEmpty(myString : string; myDelimiters : string):TStringDynArray; 
var 
    words_array_pre : TStringDynArray; 
    words_array_pos : TStringDynArray; 
    array_length : Integer; 
    actual_length : Integer; 
    current_word : string; 

    procedure AddElement(const Str: string); 
    begin 
     words_array_pos[actual_length]:= Str; 
     inc(actual_length); 
    end; 
begin 
    words_array_pre:= SplitString(myString, whitespaceNewLineCharacterSet + punctuationCharacterSet); 
    array_length:= Length(words_array_pre); 
    if (array_length >0) then 
    begin 
     actual_length:= 0; 
     SetLength(words_array_pos, array_length); 
     for current_word in words_array_pre do 
     begin 
     if (current_word <> '') then 
      AddElement(current_word); 
     end; 
     SetLength(words_array_pos, actual_length); 
     result:= words_array_pos; 
    end 
    else 
     result:= words_array_pre; 
end; 
+0

Рассматривали ли вы просто делать то, что делает SplitString, но без учета пустых элементов в результате? –

ответ

2

Это невозможно удалить определенные элементы массива без перебора массива - как еще вы знаете, какие элементы для удаления? Улучшения, внесенные в ваш код, - это удаление необходимости выделения дополнительных массива. Вы можете отбраковать исходный массив на месте:

function SplitStringNoEmpty(const s, delimiters: string): TStringDynArray; 
var 
    Src, Dest: Integer; 
begin 
    Result := SplitString(s, delimiters); 
    if Length(Result) <> 0 then begin 
    // Push all non-empty values to front of array 
    Dest := 0; 
    for Src := 0 to High(Result) do 
     if Result[Src] <> '' then begin 
     if Src <> Dest then 
      Result[Dest] := Result[Src]; 
     Inc(Dest); 
     end; 
    // Remove excess from end of array 
    SetLength(Result, Dest); 
    end; 
end; 
+0

Спасибо за оптимизацию Rob! В StrUtils должна быть добавлена ​​аналогичная функция. –

3

Вы можете написать свою собственную реализацию функции SplitString не обращая внимания на пустые строки.

Проверить этот образец

function SplitString2(const S, Delimiters: string): TStringDynArray; 
var 
    LIndex, SIndex, FIndex, LMax, LPos: Integer; 
    foo : string; 
begin 
    Result := nil; 

    if S <> '' then 
    begin 
    LPos := 0; 
    LMax := 0; 
    SIndex := 1; 

    for LIndex := 1 to Length(S) do 
     if IsDelimiter(Delimiters, S, LIndex) then Inc(LMax); 

    SetLength(Result, LMax + 1); 

    repeat 
     FIndex := FindDelimiter(Delimiters, S, SIndex); 
     if FIndex <> 0 then 
     begin 
     foo:= Copy(S, SIndex, FIndex - SIndex); 
     if foo<>'' then 
     begin 
      Result[LPos] := foo; 
      Inc(LPos); 
     end; 
     SIndex := FIndex + 1; 
     end; 
    until (LPos = LMax) or (FIndex=0); 

    if LPos<LMax then 
    SetLength(Result, LPos + 1); 

    foo:=Copy(S, SIndex, Length(S) - SIndex + 1); 
    if foo<>'' then 
    Result[LMax] := foo 
    else 
    SetLength(Result, LPos); 
    end; 
end; 

 Смежные вопросы

  • Нет связанных вопросов^_^