Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: JSON ja moniulotteinen taulukko

Sivun loppuun

pistemies [01.02.2014 16:11:54]

#

kysympähän täältä hiukan neuvoa pikku ongelmaan.

Minulla on array, joka php:lla näyttää tältä:

[0] => Array
        (
            [id] => 1
            [name] => Nimi 1
            [date] => 2012-12-03
        )

    [1] => Array
        (
            [id] => 2
            [name] => Nimi 2
            [date] => 2012-12-03
        )

    [2] => Array
        (
            [id] => 3
            [name] => Nimi 3
            [date] => 2012-12-03
        )

Se haetaan ajaxilla ja muutetaan json_encodella luettavaan muotoon.
Sen jälkeen muuttelen sen javascript arrayksi:

var array =  $.parseJSON(data);

Tuo ei kuitenkaan ole vielä normaali moniulotteinen javascript-array.

Tämä ilmoitta undefined:

alert(array[0][name]);

Tarkoitus on ajella se javascriptin for silmukassa.
Miten tuota pitäisi vielä käsitellä?

Mod. huom: PHP:n print_r-funktion tuloste ei ole PHP-koodia!

feenix [01.02.2014 16:20:30]

#

Tarkoitat varmaankin:

alert(array[0].name);

Jos yrität indeksoida name:lla, se tarkoittaa, että sinulla on muuttuja name, jonka arvoa tuossa käytetään. PHP ei tuossa tulosta JSONnia eikä mitään Javascriptin ymmärtämää, ainoastaan ihmisluettavan muodon oliosta.

Eikä tuosta tule moniulotteista javascript-taulukkoa, normaalia tai epänormaalia. Se on yksiulotteinen taulukko, joka sisältää olioita. JSONia katselemalla ymmärtänet paremmin miten se toimii.

Metabolix [01.02.2014 16:30:32]

#

Voit kyllä kirjoittaa myös näin:

alert(array[0]["name"]);

Ei ole sen kummempi kuin PHP:ssä: ethän siinäkään kirjoita name vaan "name".

Voisit myös opetella, että print_r-funktion tuloste ei ole PHP-koodia eikä siis kuulu PHP-kooditageihin. Jos haluat tulostaa muuttujia PHP-koodina, käytä vaikka funktiota var_export. Toisaalta tässä kysymyksessä aiheena oli JSON, joten olisit voinut näyttää ensisijaisesti JSON-koodin, jonka saa json_encode-funktion asetuksella JSON_PRETTY_PRINT vieläpä tulostettua ymmärrettävässä muodossa.

pistemies [01.02.2014 16:40:32]

#

feenix kirjoitti:

Tarkoitat varmaankin:

alert(array[0].name);

Kiitos. Sain tällä toimimaan.

The Alchemist [01.02.2014 16:46:32]

#

Sen verran olisi hyvä ymmärtää geneerisestä ohjelmoinnista, ettei array salli yleisesti muunlaisia indeksejä kuin 0-alkuisen juoksevan numeroinnin. Eli siis perättäisiä numeroita 0, 1, 2, 3 jne. Jos indeksi on jotain muuta tyyppiä, niin kyse on jostain muusta tietotyypistä, jota voidaan nimittää assosiatiiviseksi taulukoksi. Itse asiassa eri ohjelmointikielissä voi olla useita eri assosiatiivisen taulukon toteutuksia, joilla on jokaisella tietyt karakteristiset ominaisuudet suorituskykyä ajatellen. Php on aivottomasti suunniteltu siten, että array yrittää kattaa molemmat tapaukset, mutta tämä yritys on oikeastaan surkea epäonnistuminen.

Tämänhän minä toki kerroin sinulle jo kuukausi sitten aiemmassa ketjussasi, joten kumma kun piti taas muistuttaa.

Antti Laaksonen [01.02.2014 17:26:22]

#

The Alchemist kirjoitti:

Itse asiassa eri ohjelmointikielissä voi olla useita eri assosiatiivisen taulukon toteutuksia, joilla on jokaisella tietyt karakteristiset ominaisuudet suorituskykyä ajatellen. Php on aivottomasti suunniteltu siten, että array yrittää kattaa molemmat tapaukset, mutta tämä yritys on oikeastaan surkea epäonnistuminen.

PHP:n taulukko on pikemminkin nerokas keksintö kuin surkea epäonnistuminen. Miksi pitäisi olla erilainen taulukko sen mukaan, ovatko indeksit kokonaislukuja vai jotain muuta? PHP:n taulukko on toteutettu hajautuksen avulla, mikä on tehokasta kaikkien indeksien kanssa.

The Alchemist kirjoitti:

Sen verran olisi hyvä ymmärtää geneerisestä ohjelmoinnista, ettei array salli yleisesti muunlaisia indeksejä kuin 0-alkuisen juoksevan numeroinnin.

Niin, jos pitää geneerisenä ohjelmointina C-kieltä ja sen seuraajia. Tämä on täysin keinotekoinen rajoitus, joka oli ehkä perusteltavissa 70-luvulla mutta ei nykypäivänä.

jlaire [01.02.2014 18:15:28]

#

Myös Luassa käytetään samaa tietorakennetta sekä assosiatiivisiin että tavallisiin taulukoihin. JavaScriptissä on erikseen Array-tyyppi, mutta sekin tukee merkkijonoavaimia jos sellaisia haluaa asettaa.

Kyseessä ei ole pelkästään PHP:n oikku, vaikka on totta että termillä "array" viitataan yleensä yksinkertaiseen C-tyyliseen taulukkoon eikä assosiatiiviseen taulukkoon.

Merri [01.02.2014 19:48:54]

#

Pitää kyllä tarkentaa tuota jlairen kuvausta JavaScriptin taulukoista. On totta, että JavaScriptin Array-objektiin voi asettaa merkkijono"avaimia", mutta se ei tarkoita sitä, että lopputulos olisi odotetunlainen. Koodiesimerkki:

var test = [];

test[0] = 'Nolla';
console.log(test.length); // = 1

test.push('Yksi');
console.log(test.length); // = 2

test['2'] = 'Kaksi';
console.log(test.length); // = 3

test.kolme = 'Kolme';
console.log(test.length); // = 3

test['neljä'] = 'Neljä';
console.log(test.length); // = 3

console.log(test.join(' ')); // = 'Nolla Yksi Kaksi'

Jos tämä lopputulos häkellyttää, niin sitten on jäänyt JavaScriptin perusteista olennaisia asioita välistä. JavaScriptissä kaikki ovat objekteja, myös kaikki vakiotyyppejä kuten taulukoita tai merkkijonoja säilövät tietotyypit. JavaScript ei aseta lähes mitään rajoituksia objektien käsittelylle, joten taulukko-objektiin on mahdollista asettaa taulukon ulkopuolisia ominaisuuksia (properties). Tämä ei kuitenkaan tarkoita sitä, että JavaScriptin taulukot tukisivat merkkijonoavaimia. Eivät tue.

Array-objekti on erikoistapaus, joka osaa yhdistää numeeriset avaimet taulukkoon. Kaikki muu väkertely objektin ympärillä jätetään kuitenkin huomioitta. Selkeyden vuoksi on parasta, ettei Array-objektiin tunkata mitään muuta kuin numeerisia indeksejä. Muuten päädytään myöhemmin helposti tilanteeseen, että joku koodia seuraavaksi lukeva huutaa isoon ääneen jotain Putkankin mittapuulla painokelvotonta tekstiä.

jlaire [01.02.2014 19:56:13]

#

Hallitsen JavaScriptin perusteet mielestäni ihan hyvin. Tarkoitukseni ei ollut hijackata tätä ketjua, mutta menköön.

Merri kirjoitti:

JavaScriptissä kaikki ovat objekteja, myös kaikki vakiotyyppejä kuten taulukoita tai merkkijonoja säilövät tietotyypit.

Tarkennetaan nyt sitten vielä tätäkin: kaikki arvot eivät ole objekteja.

var str = "abc";
str.foo = "!!!!!";
console.log(str.foo); // undefined

var num = 5;
num.foo = "!!!!!";
console.log(num.foo); // undefined

Arrayt ja tavalliset objektit eivät ole hirveän kaukana toisistaan:

var xs = ["a", "b", "c"];
console.log(xs[0]); // "a"
console.log(xs['0']); // "a"

var obj = { "0": "a" };
console.log(obj[0]); // "a"

Kaikkia avaimia käsitellään merkkijonoina. Array on tavallaan tiettyyn käyttötarkoitukseen optimoitu objekti.

Metabolix [01.02.2014 20:22:47]

#

jlaire on aivan oikeassa: ECMAScript-standardissa taulukko kuvataan objektiksi, jolla on erityinen length-jäsen: kun lisätään ominaisuuksia, joilla on sopiva numeerinen avain (0–4294967294), length muuttuu automaattisesti yhden suuremmaksi kuin suurin tällainen avain, ja kun length asetetaan, kaikki liian suuret avaimet poistetaan. Siis ei ole kysymys siitä, mitä taulukot tukevat, vaan siitä, mitä length tarkoittaa. Ehkä olisi selvempää (joskin vaivalloista), jos length olisikin nimeltään greatestNumericIndexLessThan4294967295PlusOne.

Edellisiin esimerkkeihin lisään kuitenkin vielä nämä hauskat:

var str = new String("abc");
str.foo = "!!!!!";
console.log(str.foo); // "!!!!!"

var num = new Number(5);
num.foo = "!!!!!";
console.log(num.foo); // "!!!!!"

jlaire [01.02.2014 20:50:58]

#

Wrapperit on kivoja. <3

var bool = new Boolean(false);
if (bool) {
    console.log("8D");
}

The Alchemist [01.02.2014 22:52:42]

#

Antti Laaksonen kirjoitti:

The Alchemist kirjoitti:

Itse asiassa eri ohjelmointikielissä voi olla useita eri assosiatiivisen taulukon toteutuksia, joilla on jokaisella tietyt karakteristiset ominaisuudet suorituskykyä ajatellen. Php on aivottomasti suunniteltu siten, että array yrittää kattaa molemmat tapaukset, mutta tämä yritys on oikeastaan surkea epäonnistuminen.

PHP:n taulukko on pikemminkin nerokas keksintö kuin surkea epäonnistuminen. Miksi pitäisi olla erilainen taulukko sen mukaan, ovatko indeksit kokonaislukuja vai jotain muuta? PHP:n taulukko on toteutettu hajautuksen avulla, mikä on tehokasta kaikkien indeksien kanssa.

No siksi on tyhmää, että se on sekavaa. Se on sekavaa paitsi siksi, että on epäselvää, milloin funktion pitäisi palauttaa assosiatiivinen taulukko ja milloin "perinteinen" taulukko, mutta myös siksi, että taulukon käpistely yleensäkin on hyvin epäintuitiivista. Php:n tapauksessa on päädytty duplikoimaan joitakin funktioita, jolloin yksi versio säilyttää alkuperäiset indeksit ja toinen versio resetoi indeksit juoksevaan numerointiin. Toisaalta osa funktioista taas osaa suoraan käsitellä molempia tyyppejä.

Esimerkki:

$arr = ['a', 'b', 'c', 'd'];
unset($arr[2]);

$brr = [];
$brr[3] = 2;

Pitäisikö taulukossa $arr nyt olla indeksit 0-2 vai 0, 1 ja 3? Entäs taulukko $brr, pitäisikö siinä olla sijoituksen jälkeen yksi vai kolme solua? (Tai pitäisikö tulla jonkinlainen virhe, koska yritetään sijoittaa liian suureen indeksiin?)

Jos kokee assosiatiivisen taulukon uskomattoman hienoksi keksinnöksi mihin tahansa, niin eihän mikään estä käyttämästä c++:ssakaan jotain containeria int-tyyppisillä indekseillä.

P.S.

$a = [1 => 'a', 2 => 'b', 3 => 'c', 'foo' => 'bar'];
array_shift($a);
// Taulukko on nyt tällainen:
// [0 => 'b', 1 => 'c', 'foo' => 'bar']

pistemies [02.02.2014 12:10:05]

#

The Alchemist kirjoitti:

Jos kokee assosiatiivisen taulukon uskomattoman hienoksi keksinnöksi

Vaikka mysql-tietokannassa sarakkeiden nimet voi asettaa tavallisen arrayn tapaan 0-3, on tuo assosiatiivinen taulukko huomattavasi selkeämpi.

The Alchemist [02.02.2014 14:32:50]

#

Jos halua vain säilöä olioita listaan, niin olisi aika hölmöä, jos jokaisen olion kohdalla pitäisi keksiä indeksille nimi, eikä voisi vain käskeä tyyliin list.append(olio).

pistemies [02.02.2014 15:30:05]

#

The Alchemist kirjoitti:

Jos halua vain säilöä olioita listaan, niin olisi aika hölmöä, jos jokaisen olion kohdalla pitäisi keksiä indeksille nimi, eikä voisi vain käskeä tyyliin list.append(olio).

Tietokanta harvoin on pelkkä säilöntäpurkki.
Monessa tapauksessa sitä on tarve muokata joidenkin sarakkeiden osalta ja tällöin joutuu nimeämään, mitä sarakkeita päivitetään.

Tästäpä voipi valita, kumpiko päivitystapa on kivempi:

UPDATE taulu SET `name` = 'Asko' WHERE `id` = 2
UPDATE taulu SET `3` = 'Asko' WHERE `0` = 2

Lebe80 [02.02.2014 16:38:54]

#

pistemies kirjoitti:

The Alchemist kirjoitti:

Jos halua vain säilöä olioita listaan, niin olisi aika hölmöä, jos jokaisen olion kohdalla pitäisi keksiä indeksille nimi, eikä voisi vain käskeä tyyliin list.append(olio).

Tietokanta harvoin on pelkkä säilöntäpurkki.
Monessa tapauksessa sitä on tarve muokata joidenkin sarakkeiden osalta ja tällöin joutuu nimeämään, mitä sarakkeita päivitetään.

Tästäpä voipi valita, kumpiko päivitystapa on kivempi:

UPDATE taulu SET `name` = 'Asko' WHERE `id` = 2
UPDATE taulu SET `3` = 'Asko' WHERE `0` = 2

Vaikka yhteläisyyksiä onkin paljonkin riippun käyttötavoista, niin silti:

Lista != tietokanta

The Alchemist [02.02.2014 16:44:26]

#

Tarkoitukseni oli vain rivien välistä teroittaa, että sopivasti valitun erikoistapauksen käyttö oman kantansa todistelussa on joskus hyödytöntä. Oikeastaanhan tuo pistemiehen esimerkki puhuu vain sen puolesta, mistä itse alkujaan kirjoitin, eli että juoksevalla numeroinnilla toimivan listan ja assosiatiivisen taulukon yhdistäminen ei voi toimia. Niillä on molemmilla omat käyttötarkoituksensa.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta