PDA

Ver la Versión Completa : Practica de arrays


JuanOrtega
28-12-2015, 16:11:14
Hola estoy practicando con los arrays normales en delphi , no con stringlist ni nada parecido.

Este el codigo que tengo :


type
otro_array = array of string;

function clean_array(array1: otro_array): otro_array;
var
array_limpio: otro_array;
i: integer;
begin
For i := Low(array1) to High(array1) do
begin
ShowMessage(array1[i]);
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
const
datos: array [1 .. 5] of string = ('test1', 'test2', 'test3',
'test4', 'test5');
var
arrays: Array Of String;
i: integer;
begin

SetLength(arrays, 5);

arrays[0] := 'test1';
arrays[1] := 'test2';
arrays[2] := 'test3';
arrays[3] := 'test4';
arrays[4] := 'test5';

clean_array(datos);
clean_array(arrays);


Iba todo bien haciendolo solo , hasta que me aparecieron dos errores que no se como resolver.

En la linea clean_array(datos); me devuelve este error :

Incompatible types: 'otro_array' and 'Array'

En la linea clean_array(arrays); me devuelve este error :

Incompatible types: 'otro_array' and 'Dynamic array'

En tema es que no se como resolverlo , no se si tengo que convertirlo o en realidad no se puede hacer lo que intento con estos dos arrays.

¿ Alguien me podria ayudar ?

AgustinOrtu
28-12-2015, 17:06:40
Si eliminas el tipo otro_array y dejas todo como array of string no hay problemas

Que necesitas hacer exactamente?

La funcion clean_array recibe un array de string y debe llenarlo con string vacios?

JuanOrtega
28-12-2015, 18:07:00
Tengo que usar el :

type otro_array = array of string;

de todas formas , porque voy a hacer dos funciones que reciben y retornan otro_array porque ArrayOfString me daba error cuando lo ponia como argumento y mas como retorno , son dos funciones que limpian string y esas cosas , pero me clave aca que es donde mando el array otro_array a una de las dos funciones y muestra estos errores.

AgustinOrtu
28-12-2015, 19:43:21
Que version de Delphi estas usando? Si soporta genericos podrias hacer algo como esto:


function UnaFuncion(Array: TArray< String >): TArray< string >;
begin
...
end;


Aun no me dijiste que es exactamente lo que queres hacer.

Por el nombre de la funcion "clean_array" me da la sensacion de que queres iterar sobre todo el arreglo y asignar en cada posicion EmptyStr (string vacio, '')

Pero para ese caso no te haria falta una funcion y lo mas logico seria pasar el arreglo como parametro por referencia a un metodo, asi:


procedure Clean_Array(var Array: TArray< String >);
var
I: Integer;
begin
for I := Low(Array) to High(Array) do
Array[I] := EmptyStr; / '', como mas te guste
end;


Si no especificas var, el arreglo que recibe tu funcion es una copia, entonces todos los cambios que hagas no se ven reflejados en la variable original con la que llamas al metodo

Al especifcar var, no se copia el arreglo, sino que lo que recibe el metodo es la direccion de memoria del arreglo, entonces en ensencia es el mismo arreglo

ecfisa
28-12-2015, 22:16:03
Hola Lepuke.

...
Iba todo bien haciendolo solo , hasta que me aparecieron dos errores que no se como resolver.

En la linea clean_array(datos); me devuelve este error :
Incompatible types: 'otro_array' and 'Array'

Eso es por que la función clean_array espera como argumento un valor de tipo: otro_array y le estas enviando uno de tipo: array [1 .. 5] of string.



En la linea clean_array(arrays); me devuelve este error :
Incompatible types: 'otro_array' and 'Dynamic array'

La misma situación... Se espera un tipo: otro_array y le estas enviando un tipo: array of string.

No sé que es lo que estas buscando específicamente, pero te pongo un ejemplo de como podes pasar tu tipo (en este caso un arreglo dinámico) tanto por valor como por referencia.

...
type
TDynArrayStr = array of string;

procedure InitDynArray(var Dyn: TDynArrayStr);
const
CSTR : array[1..5] of string = ('st1', 'st2', 'st3', 'st4', 'st5');
begin
SetLength(Dyn, Length(CSTR));
Move(CSTR, Dyn[0], Length(CSTR)*SizeOf(string));
end;

procedure CleanDynArray(var Dyn: TDynArrayStr);
var
l: Integer;
begin
l := Length(Dyn);
Finalize(Dyn);
SetLength(Dyn, l);
end;

function NumberDynArray(Dyn: TDynArrayStr): TDynArrayStr;
var
i: Integer;
begin
SetLength(Result, Length(Dyn));
for i := Low(Dyn) to High(Dyn) do
Result[i] := Format('%d) %s',[i, Dyn[i]]);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
v: TDynArrayStr;
i: Integer;
begin
CleanDynArray(v);
InitDynArray(v);
v:= NumberDynArray(v);

for i := Low(v) to High(v) do
ListBox1.Items.Add(v[i]);

v := nil;
end;


Saludos :)

JuanOrtega
31-12-2015, 02:51:59
gracias por la ayuda ecfisa , lo que estoy haciendo es limpiar repetidos en arrays of string , el codigo que tengo hasta ahora es este :


type
otro_array = array of string;

function clean_array(const array1: array of string): otro_array;
var
array_limpio: otro_array;
i: integer;
i2: integer;
begin
For i := Low(array1) to High(array1) do
begin
For i2 := Low(array_limpio) to High(array_limpio) do
begin
if (array_limpio[i2] = array1[i]) then
begin
SetLength(array_limpio, Length(array_limpio) + 1);
array_limpio[Length(array_limpio)] := array1[i];
end
end;
end;
Result := array_limpio;
end;

procedure TForm1.Button1Click(Sender: TObject);
const
datos: array [1 .. 5] of string = ('test1', 'test2', 'test3',
'test4', 'test5');
var
arrays: Array Of String;
array_limpio: otro_array;
i: integer;
begin

SetLength(arrays, 5);

arrays[0] := 'test1';
arrays[1] := 'test2';
arrays[2] := 'test1';
arrays[3] := 'test4';
arrays[4] := 'test1';

array_limpio := clean_array(arrays);
// clean_array(arrays);

For i := Low(array_limpio) to High(array_limpio) do
begin
ShowMessage(array_limpio[i]);
end;


Creo que pense el tema muy mal porque mi funcion clean_array() no devuelve ni detecta nada , ¿ que hice mal ?

ecfisa
31-12-2015, 04:36:43
gracias por la ayuda ecfisa , lo que estoy haciendo es limpiar repetidos en arrays of string ...

Intentalo al modo de este ejemplo:

type
otro_array = array of string;

function clean_array(const v: array of string): otro_array;
var
i,j: integer;
sw : Boolean;
begin
for i := Low(v) to High(v) do
begin
sw := False;
for j := i+1 to High(v) do
if v[i] = v[j] then sw := True;
if not sw then
begin
SetLength(Result, Length(Result)+1);
Result[High(Result)] := v[i];
end;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
arrays: array of string;
array_limpio: otro_array;
i: integer;
begin
SetLength(arrays, 5);
arrays[0] := 'cad1';
arrays[1] := 'cad2';
arrays[2] := 'cad1';
arrays[3] := 'cad4';
arrays[4] := 'cad1';

ListBox1.Items.Add('Todos los elementos');
ListBox1.Items.Add('---------------------------');
for i:= Low(arrays) to High(arrays) do
ListBox1.Items.Add(arrays[i]);
ListBox1.Items.Add('');

ListBox1.Items.Add('Quitando los repetidos');
ListBox1.Items.Add('---------------------------');
array_limpio := clean_array(arrays);
for i := Low(array_limpio) to High(array_limpio) do
ListBox1.Items.Add(array_limpio[i])

Finalize(arrays);
Finalize(array_limpio);
end;


Saludos :)

JuanOrtega
31-12-2015, 19:05:28
gracias por siempre ayudarme ecfisa , tu codigo funciona perfecto , una pregunta , ¿ porque los repetidos siempre terminan al final de array ? , te lo pregunto porque no veo el porque.

ecfisa
31-12-2015, 19:59:12
Hola Lepuke.
...
¿ porque los repetidos siempre terminan al final de array ? , te lo pregunto porque no veo el porque.
Surge de la lógica con que implementé la función clean_array. Si le realizas una prueba de escritorio (http://www.israelcapetillo.com/2015/04/pruebas-de-escritorio-aliadas-del.html) enseguida vas a notar el por que.

Saludos :)

JuanOrtega
01-01-2016, 01:13:30
Ok , gracias por la ayuda ecfisa.