Jak přidat element na začátek pole? Je na to nějaká funkce?
Fórum › Delphi
Jak přidat element na začátek pole?
#1 oxidián
u pole nebo u listu? U listu by to šlo metodou insert
u Array podle toho jestli máš rezervu ve velikosti a počátáš si vlastní count nebo je velké akorát, takže nejdříve případne zvětšit kapacitu pole pomocí
SetLength(pole,velikost);
poté posunout všechny prvky na konec nutno jít od konce tzn downto cyklus
no a nakonec doplnit ten prvek pole[0] := ...
lze použít i na vložení na jakoukoliv pozici v poli
#3 oxidián
// pokud nepracuješ s dostatečně velkým polem, kde máš rezervu
//nebo je pole plné
SetLength(FiltryCheckedArrayList, length(FiltryCheckedArrayList)+1);
//vytvoření místa na dané pozici, pro začátek pozice:=0
for i := length(FiltryCHeckedArrayList)-2 to pozice step -1
FiltryCheckedArrayList[i+1] := FiltryCheckedArrayList[i];
next;
FiltryCheckedArrayList[pozice] := novyStrings;
#4 MilanL
OK jasný, takže přímo na to v delphi není funkce, musím si napsat. Dík.
procedure arrayInsert(var arr: Array of TStrings; var str: TStrings);
var i,pozice:integer;
begin
pozice := 0;
SetLength(arr, length(arr)+1);
//vytvoření místa na dané pozici, pro začátek pozice:=0
for i := length(arr)-2 to pozice step -1
arr[i+1] := arr[i];
next;
arr[pozice] := str;
end;
vrací chybu SetLength(arr, ... incompatible types
Jak tam dostat ten argument var arr?
Takto nelze do funkce předávat dynamický array. Jak to máš deklarované tak parametr arr je open array (použij google pro detaily), musíš si nadefinovat typ pro to pole, a ten typ pak použít pro daný parametr.
type
TStringsObjArray = array of TStrings;
procedure arrayInsert(var arr: TStringsObjArray; str: TStrings);
...
Díky. A nerozumím tomu:
for i := length(arr)-2 to pozice step -1
arr[i+1] := arr[i];
next;
co je step? Schází tam DO.
Má to být takto?
type
TStringsObjArr = array of TStrings;
procedure arrayInsert(var arr: TStringsObjArr; var str: TStrings);
var i,pozice:integer;
begin
pozice := 0;
SetLength(arr, length(arr)+1);
//vytvoření místa na dané pozici, pro začátek pozice:=0
for i := length(arr)-2 to pozice DO
i:= -1
arr[i+1] := arr[i];
next;
arr[pozice] := str;
end;
STEP ve většině dialektů pascalu (delphi nevyjímaje) není. Celkově to vypadá jak z jiného jazyka (NEXT taky v pas není).
type
TStringsObjArr = array of TStrings;
procedure arrayInsert(var arr: TStringsObjArr; str: TStrings);
var
i: integer;
begin
SetLength(arr,length(arr)+1);
For i := High(arr) downto Succ(Low(arr)) do
arr[i] := arr[i - 1];
arr[0] := str;
end;
Když předáváš v parametru objekt, NIKDY to nedeklaruj jako var pokud k tomu není opravdu vážný důvod.
#1 oxidián
Zkus se zamyslet, zda by nebylo lepší mít to pole pozpátku a položky přidávat na konec. Přidávání na začátek je totiž drahé.
Často však bývá výhodnější použití seznamu, zásobníku nebo fronty. Pracuje se s tím mnohem lépe a výkon netrpí.
Teď se chci zeptat jak vyplnit
list: Tstrings;
polem? Je nějaká funkce abych zavolal něco jako list.fromArray(myArray); ty položky se automaticky přidají z pole do seznamu? Nebo musím pokaždé vytvářet vlastní cyklus? Já už viděl podobné funkce, že ze souboru se načte seznam, tak myslím, že by mohlo být i toto. Což o to, napsat to přes for, mohu, ale raději chci využívat ty chytré funkce je to přehlednější a kratší kód.
#9 Kit
Ale tady to není PHP. Je tam deset položek v poli :-) Mě už to jede.
#14 Kit
Co kdybys přestal filosofovat a poskytl konkrétní odpověď na moji otázku. Existuje taková funkce nebo ne?
Dit: už jsem to prozkoumal, a odpověděl jsem si: ne. Takže si to napíšu
#17 oxidián
Není. Proto jsem psal, že bys neměl být líný si ji napsat. Pokud takové posuny potřebuješ dělat častěji, tak se hodí posunout o víc než jednu položku a udržovat si index začátku.
Jenom doufám, že neprogramuješ nějaké řazení. U toho se používají jiné postupy.
#8 Sniper
Důvod proč deklaruju arr jako var, je ten, že ta funkce rozšiřuje to pole o jeden element.
procedure arrayInsert(var arr: TStringsObjArr);
var i,pozice:integer;
begin
i := length(arr);
SetLength(arr, i+1);
for i := length(arr)-2 downto 0 DO
arr[i+1] := arr[i]; // copy array element
end;
Kdyby tam nebylo var, tak po ukončení funkce, bude mít pole opět stejnou hodnotu a hodnoty, které jsem zkopíroval zmizí.
Implementace:
arrayInsert(Self.FiltryCheckedArrayList);
Result before call:
TestyOrganizer.FiltryCheckedArrayList[0][0] = 'filtry.cfg'
TestyOrganizer.FiltryCheckedArrayList[0][1] = '1'
TestyOrganizer.FiltryCheckedArrayList[1][0] = not accessible
TestyOrganizer.FiltryCheckedArrayList[1][1] = not accessible
Result After call:
TestyOrganizer.FiltryCheckedArrayList[0][0] = 'filtry.cfg'
TestyOrganizer.FiltryCheckedArrayList[0][1] = '1'
TestyOrganizer.FiltryCheckedArrayList[1][0] = 'filtry.cfg'
TestyOrganizer.FiltryCheckedArrayList[1][1] = '1'
Nyní ale řeším další problém. Další řádka je:
Self.FiltryCheckedArrayList[0][0] := s;
A výsledek je:
TestyOrganizer.FiltryCheckedArrayList[0][0] = 'filtry oblíbené.cfg'
TestyOrganizer.FiltryCheckedArrayList[0][1] = '1'
TestyOrganizer.FiltryCheckedArrayList[1][0] = 'filtry oblíbené.cfg'
TestyOrganizer.FiltryCheckedArrayList[1][1] = '1'
Což nemělo nastal. Mělo být:
TestyOrganizer.FiltryCheckedArrayList[0][0] = 'filtry.cfg'
TestyOrganizer.FiltryCheckedArrayList[0][1] = '1'
TestyOrganizer.FiltryCheckedArrayList[1][0] = 'filtry oblíbené.cfg'
TestyOrganizer.FiltryCheckedArrayList[1][1] = '1'
Nechápu jak mohlo dojít k tomu, že 2. element odkazuje na 1. index???
Edit:
Už chápu, způsobuje to ta řádka: arr[i+1] := arr[i]; je třeba to nadefinovat jako pole a zkopírovat hodnoty ze seznamu.
Takže to mám správně to má být takto:
procedure arrayInsert(var arr: TStringsObjArr);
var i,pozice:integer;
begin
i := length(arr);
SetLength(arr, i+1);
for i := length(arr)-2 downto 0 DO
begin
arr[i+1] := TStringList.Create;
arr[i+1].AddStrings(arr[i]);
end;
end;
Takže ta funkce z #3 od Milana byla úplně naho*no, jen mě to zdrželo asi tak o šest hodin.
#19 oxidián
Takže to mám správně to má být takto
NE! Když už ty prvky kopíruješ vytvářením nových, tak ještě musíš mazat ty staré.
Ale ty nepotřebuješ vytvářet nové objekty. Jen chceš ty původní posunout.
A samozřejmě když takhle kopíruješ každý prvek na další pozici, tak nakonec bude kopie první položky na druhé pozici, ale zároveň zůstane i na první pozici. To je to nově vytvořené místo, které je potřeba inicializovat.
Já bych to kopírování teda ještě otočil ať tam nestraší to -2.
setlength(arr, length(arr)+1);
for i := length(arr)-1 downto 1 do
arr[i] := arr[i-1];
arr[0] := tstringlist.create;
Co ti na takové kravině trvalo 6 hodin?
Přidej příspěvek
Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku
×Vložení zdrojáku
×Vložení obrázku
×Vložení videa
Uživatelé prohlížející si toto vlákno
Podobná vlákna
Pridať textové pole cez odkaz — založil zelenac1
StringGrid - jak přidat text — založil Borisek
Jak přidat Pydev do Eclipse — založil basfot
Maven - jak pridat knihovnu — založil pepa