Kolekce a pole

11. díl - Kolekce a pole

Tomáš Herceg       27.07.2007       VB.NET, .NET       21416 zobrazení

V tomto díle seriálu se budeme podrobněji věnovat polím a kolekcím. Zaprogramujete si také trochu sami, protože pro vás je připraveno pět jednoduchých úkolů na práci s polem. Zvládnete je? Doufám, že ano.

Přestože jsme o polích již mluvili dříve a o kolekcích jsem se také párkrát zmínil, přestože jsem se o tom moc nerozepisoval, je toho ještě mnoho, co nevíme. Nejprve si zopakujeme pole, abychom mohli pokračovat dál.

Dim pole(5) As Integer
Dim pole() As Integer = {5, 476, 2, 4, 14, 16}
Dim pole(3, 2) As Integer

První řádek vytvoří prázdné pole o velikosti 6 prvků (prvek 0 až prvek 5). Druhý řádek vytvoří pole (také o velikosti 6, ale tu nezadáváme, prvky se spočítají automaticky) a předvyplní do něj hodnoty ve složené závorce. Třetí řádek vytvoří dvourozměrné pole o velikosti 4x3 prvky.

Dim pole() As Integer = {5, 476, 2, 4, 14, 16}

For i As Integer = 0 To pole.Length - 1
  'pro každý prvek pole
  MsgBox(pole(i))
Next

Tato ukázka vypíše v MessageBoxu postupně všechny prvky pole. Řádek MsgBox(pole(i)) se postupně spustí pro i=0 až i=pole.Length - 1. Výraz pole.Length vrátí počet prvků v poli (tedy 6), jedničku odečítáme, protože se prvky číslují od nuly. Pro první MessageBox se tedy za i dosadí 0, tím pádem bude pole(i) rovno 5, takže MessageBox ukáže pětku. Pak se za i dosadí 1 a MessageBox ukáže 476. A tak to pokračuje až do i=5.

Hry s čísly

Abychom si pole trochu procvičili, spusťte si Visual Basic a zkuste si vyřešit tyto úkoly. Až budete hotovi, klikněte na odkaz Ukázat řešení. Můžete se podívat, jestli jste postupovali správně, případně kde máte chybu.

Zadání úkolů

Zadání je prosté. Máme zadáno toto pole o velikosti 20 prvků. V každé úloze musíte použít alespoň jeden cyklus For.

Dim pole(19) As Integer

Pokud si chcete ověřit, jestli vaše programy vyplnily pole správně, přidejte na konec procedury tento kód, který zapíše všechny prvky do proměnné t typu String a pak ji vypíše v MessageBoxu.

'výpis hodnot pole
Dim t As String = pole(0)
For i As Integer = 1 To 19
    t &= ", " & pole(i)
Next
MsgBox(t)

Úkoly

1) Napište program, který do jednotlivých prvků tohoto pole vypíše čísla od 10 do 29.

2) Napište program, který do jednotlivých prvků pole vypíše postupně násobky 3.

3) Napište program, který prvnímu prvku přiřadí číslo 1 a do každého dalšího uloží dvojnásobek toho předchozího (tzn. 1, 2, 4, 8, 16 atd.)

4) Napište program, který do jednotlivých prvků pole vypíše postupně čísla od 20 do 1. Pole tedy bude vypadat takto: (20, 19, 18, 17 ... 2, 1).

5) Napište program, který pole vyplní tímto způsobem: (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1).

 Uvedená řešení nejsou samozřejmě jediná možná. Pro každou úlohu existuje daleko víc možností, uvedl jsem ty, které mě napadly nejdříve. Pokud jste tyto úlohy zvládli, tak je to dobře. Pokud ne, zkuste si připomenout sedmý díl tohoto seriálu.

Kolekce

V minulých dílech jsme s kolekcemi pracovali. Jen zběžně jsem napsal, že kolekce je jakési "chytřejší pole". Podíváme se na ně tedy blíže.

Každé pole má několik vlastností a tzv. metod. Pokud do Visual Basicu napíšeme název nějakého již nadeklarovaného pole a zmáčkneme tečku, prostředí si automaticky domyslí, že chceme použít právě jeho vlastnost nebo metodu a nabídne nám jejich seznam. Stejně tak to funguje u komponent a u jakýchkoliv objektů.

Pokud tedy napíšete název nějakého nadeklarovaného pole a za něj tečku, Visual Studio vám nabídne možnosti. My jsme již používali vlastnost Length pole, která vrátí počet prvků. Máme k dispozici i další metody a vlastnosti, ale těmi se zatím zabývat nebudeme.

Nyní napište Me.Controls a tečku. Me odkazuje na třídu nebo formulář, na kterém právě jsme. Každý formulář má kolekci Controls, ve které má uložený seznam všech komponent, které na něm jsou. Pokud tedy napíšeme Me.Controls a tečku, ukáže se nám seznam metod a vlastností kolekce. Je rozhodně o něco bohatší.

Kolekce je vlastně takové "nafukovací pole". Nikde není předem řečeno, jaký má počet prvků. Slouží k podobným účelům jako pole - k uchování více hodnot. My si teď řekneme o základních metodách kolekcí. Každá kolekce takové metody má (pokud není ReadOnly, tedy jen pro čtení).

Přidávání prvků do kolekce

Do kolekcí jsme již prvky přidávali (např. při plnění seznamu ListView v předminulém díle). Vytvořili jsme nový objekt ListViewItem, nastavili jsme mu nějaké hodnoty a předali jej metodě Add kolekce Listview1.Items, což je kolekce položek v tomto seznamu. Obecné schéma vypadá takto:

<kolekce>.Add(<hodnota>)

Vymazání kolekce

Občas potřebujeme vymazat všechny položky v kolekci, k tomu slouží metoda Clear.

<kolekce>.Clear()

Odstranění prvku z kolekce

Prvky můžeme z kolekce mazat. Buď máme v nějaké proměnné přímo objekt, který chceme vymazat, v takovém případě použijeme metodu Remove a objekt jí předáme, nebo známe jen jeho index v kolekci (číslovaný od nuly), proto máme metodu RemoveAt. Jakmile ale objekt smažeme, změní se pořadí objektů následujících (posune se o 1 dolů).

<kolekce>.Remove(<objekt>)
<kolekce>.RemoveAt(<pořadí v kolekci>)

Počet prvků v kolekci

Kolekce má na rozdíl od pole pro zjištění počtu prvků vlastnost Count.

Nalezení objektu v kolekci

Pokud potřebujeme získat pořadí (index) objektu, použijeme metodu IndexOf, která toto pořadí vrátí. Pokud objekt nenajde, vrátí -1, s tím je dobré počítat.

Dim index As Integer = <kolekce>.IndexOf(<objekt>)

Přímý přístup k prvku kolekce

Pokud chceme vytáhnout třetí prvek z kolekce, je to stejné jako u pole. Za název kolekce přidáme do závorky index prvku (číslovaný od nuly, takže 2).

Závěrem

 To je pro dnešek vše. Kolekce si prakticky již ukazovat nebudeme, až v některém z příštích dílů. Důležité je, že víme, jak fungují. Umíme také vytvořit objekt, takže si můžete hrát se seznamem ListView. Doufám, že vás tato dávka teorie neotrávila, příště se vrhneme na práci s textem. Pokud máte jakékoliv návrhy nebo máte pocit, že něčemu nerozumíte, pište do diskuse, pokusím se to vysvětlit lépe.

 

hodnocení článku

3 bodů / 3 hlasů       Hodnotit mohou jen registrované uživatelé.

 

 

 

Nový příspěvek

 

Mr.

1'

csharp|

xml|

css|


'

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

Diskuse: Kolekce a pole

1) Napište program, který do jednotlivých prvků tohoto pole vypíše čísla od 10 do 29.

Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim pole(19) As Integer
        'výpis hodnot pole
        Dim t As String = pole(0)
        For i As Integer = 0 To pole.Length - 1
            pole(i) = i + 10
            t &= ", " & pole(i)
        Next
        MsgBox(t)
    End Sub
End Class

Ve výsledku se místo 20 ti prvků (hodnoty 10,11,12...29)objeví

21 prvků (hodnoty: 0,10,11,12...29).Prozraďte mi prosím někdo, kde se ve výsledku vzala ta nula. Kde mám chybu ?

Dík. AKu.

nahlásit spamnahlásit spam 0 / 2 odpovědětodpovědět

Podobné je to i u úkolu č.3.

Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim pole(19) As Integer
        'výpis hodnot pole
        Dim t As String = pole(0)
        Dim j As Integer = 1

        For i As Integer = 0 To pole.Length - 1
            pole(i) = j
            t &= ", " & pole(i)
            j = j * 2
        Next
       
        MsgBox(t)
    End Sub
End Class

Opět ta nula.ve výsledku.(0,1,2,4,8,16....524288)

AKu.

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

A totéž u dalších úloh. Např.:

Uloha č.5) Napište program, který pole vyplní tímto způsobem: (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1).

Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim pole(19) As Integer
        'výpis hodnot pole
        Dim t As String = pole(0)
        Dim j As Integer = 1
        
        For i As Integer = 0 To pole.Length - 1
            If i < 10 Then
                pole(i) = i + 1
            Else
                pole(i) = 20 - i
            End If

            t &= ", " & pole(i)

        Next

        MsgBox(t)
    End Sub
End Class
Opět ta '''nula'''. Něco jsem asi ''pokazil''  nebo někde špatně četl. 
AKu.
nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

A totéž u dalších úloh. Např.:

Uloha č.5) Napište program, který pole vyplní tímto způsobem: (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1).

Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim pole(19) As Integer
        'výpis hodnot pole
        Dim t As String = pole(0)
        Dim j As Integer = 1
        
        For i As Integer = 0 To pole.Length - 1
            If i < 10 Then
                pole(i) = i + 1
            Else
                pole(i) = 20 - i
            End If

            t &= ", " & pole(i)

        Next

        MsgBox(t)
    End Sub
End Class

Opět ta nula. Něco jsem asi pokazil nebo někde špatně četl.

AKu.

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

ahoj, tie nuly sa ti vypisujú z nasledujúceho dôvodu:

1.) do t uložíš pole(0), a teda t = "0" (keďže t je dátového typu String)

2.) t &= "," & pole(i) vykoná v prvom kroku nasledujúce: do t uloží reťazec: pôvodná hodnota t (čo je momentálne "0"), potom čiarka, medzera a nakoniec aktuálna hodnota v pole(0). To znamená, že v prvom kroku predchádzajúceho príkladu bude: t = "0, 1".

Ešte jedno odporúčanie, používaj funkcie ako napr. CStr, ktoré zmení Integer na String. Ja mám napríklad nastavené Option Strict On a ak to nepoužijem tak myslím, že ma programovacie prostredie upozorní na chybu.

Dúfam, že som pomohol.

Peter

nahlásit spamnahlásit spam 0 / 2 odpovědětodpovědět

Jen upřesním kolegův příspěvek: deklarace proměnné t má vypadat takto:

Dim t As String = ""

Tedy prázdný řetězec.

Pokud se jinak nic nezmění, bude nakonec začínat čárkou, tj. ",10,11,12,...". Tu lze odfiltrovat

1) buď podmínkou v cyklu, něco jako

If i = 0 Then
    t = t & CStr(i + 10)
Else
    t = t & "," & CStr(i + 10)
EndIf

(případně testovat podmínku t = ""),

2) nebo lze na konci - za cyklem - odstranit první znak v řetězci t.

(Doufám, že kód mám dobře, píšu to teď z hlavy bez VB, na nějž se zatím ještě obvykle spoléhám ;-) )

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

Super borče

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

Diskuse: Kolekce a pole

Dobrý den,

malá technická, u druhého příkladu by i mělo jít od 1 do 20. Při Vašem zápisu se zapíše do pole(0) nula, což není násobek trojky.

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

No, já osobně nulu za násobek trojky považuji, protože 0 x 3 = 0. Nevím, jestli to je správně, ale myslím, že to je nepodstatný detail.

nahlásit spamnahlásit spam 3 / 5 odpovědětodpovědět

Nula se obvykle v tabulkách násobků neudává, ale to není problém - stačí tam dát

pole(i) = 3*(i+1)

Pro první prvek pole (i = 0) dostaneme 3, pro druhý prvek (i = 1) je výsledek 6 atd.

Dík za seriál, čerpám z něj ještě po tolika letech... :-)

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

Diskuse: Kolekce a pole

proč pišeš na konci "Next i"

nic to neudělá

tak bych chtel vedet vyznam - myslim ze jsi to tu nikde nepsal

alevypada to ze to tu docela vyhaslo a 2 roky tu nikdo nebyl..

snad mi nekdo odepise :S

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

Asi neni od veci precist si v pripade podobnych nejasnosti Microsofti help (oznacit mysi + f1).

Je to dobrovolny udaj counteru. Kdyz je vic vnorenych cyklu, je tak prehlednejsi ktery Next patri ke kteremu For a zaroven compiler cloveka upozorni, kdyz to pomota/nechtene smaze.

Viz priklad v dokumentaci:

For indexA = 1 To 3
    ' Create a new StringBuilder, which is used
    ' to efficiently build strings.
    Dim sb As New System.Text.StringBuilder()

    ' Append to the StringBuilder every third number
    ' from 20 to 1 descending.
    For indexB = 20 To 1 Step -3
        sb.Append(indexB.ToString)
        sb.Append(" ")
    Next indexB

    ' Display the line.
    Debug.WriteLine(sb.ToString)
Next indexA
' Output:
'  20 17 14 11 8 5 2
'  20 17 14 11 8 5 2
'  20 17 14 11 8 5 2

nahlásit spamnahlásit spam 0 / 2 odpovědětodpovědět

Diskuse: Kolekce a pole

Ve VB6 se velmi snadno indexují objekty - Label1(1), Label(2)...

Existuje něco podobného ve Visual Basicu 2008?

V. Sova

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

Existuje, ale nejde to naklikat, musíte si komponenty vytvořit kódem.

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

A ten kód byste nenapověděl - možná bude stačit ťuknout. Díky.

V. Sova

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

http://www.vbnet.cz/forum-tema--503-nezn...

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

Díky - funguje to.

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

Diskuse: Kolekce a pole

Na somtném začátku tohoto dílu se vloudila do přepisu malá chybyčka:

Třetí řádek vytvoří dvourozměrné pole o velikosti 4x3 prvky (myslím, že tam má být něco jiného)

nahlásit spamnahlásit spam 0 / 2 odpovědětodpovědět

Ne, je to správně. Protože pole se indexují od nuly, deklarace

Dim a(5) As Integer

udělá pole o velikosti 6 prvků. Prvním prvkem je pochopitelně a(0), posledním je a(5). Tady je totiž drobná odlišnost od ostatních jazyků, kdy při deklaraci pole udáváte počet položek. Ve VB se udává vždy index posledního prvku.

Díky tomu deklarace

Dim a(3, 2) As Integer

opravdu vytvoří pole o velikosti 4x3.

Tady jsem to již nezdůrazňoval, je to jen opakování ze 7. dílu, který se polím věnuje.

nahlásit spamnahlásit spam 1 / 3 odpovědětodpovědět

Diskuse: Kolekce a pole

%SystemRoot%\System32\Reg.exe ADD "HKCU\Control Panel\Mouse" /v MouseSensitivity /t REG_SZ /d 6 /f

Syntaxe neřve, ale příkaz se neprovede:

Dim WriteToReg

WriteToReg = Shell("C:\Windows\System32\Reg.exe ADD HKCU\Control Panel\Mouse /v MouseSensitivity /t REG_SZ /d 6 /f")

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

Odpovím si sám: Příkaz musí vypadat takto:

WriteToReg = Shell("C:\Windows\System32\Reg.exe ADD ""HKCU\Control Panel""\Mouse /v MouseSensitivity /t REG_SZ /d 6 /f")

:o)

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

Diskuse: Kolekce a pole

... těším se na pokračování.

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

Diskuse: Kolekce a pole

Diky za dalsi pokracovani.

Kejli

nahlásit spamnahlásit spam 1 / 3 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.

Nyní zakládáte pod článkem nové diskusní vlákno.
Pokud chcete reagovat na jiný příspěvek, klikněte na tlačítko "Odpovědět" u některého diskusního příspěvku.

Nyní odpovídáte na příspěvek pod článkem. Nebo chcete raději založit nové vlákno?

 

  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback