Autor Zpráva
High Voltage
Profil *
Dobrý den, chtěl bych naprogramovat skript, který by procházel proměnnou (var promena = "priklad") po písmenech; od prvního po poslední, a při tom je měnil podle zadání, například (a) proměnil v (e), nebo (v) proměnil v (x). Ale zde jsem selhal. Když bych to pole měnil najednou, přeměna (a) v (e) by se po provedení provedla opačně -> (e) v (a), a tak do nekonečna. Napište mi prosím skript, který by to zvládl, nebo alespoň metodu, nebo způsob, jak toho docílit. Děkuji za každou odpověď. :-)
Pozn.: (a), (e) ... jsou písmena a, e
Witiko
Profil
High Voltage:
Celkem jednoduše s pomocí regulárních výrazů:
"priklad".replace(/a/g, "e").replace(/v/g, "x");
High Voltage
Profil *
ale když v tom poli budu mít písmeno (a) i písmeno (v), co potom ?
nepřemění se to zpátky? Mě se to tak děje, ale díky za snahu
Witiko
Profil
High Voltage:
Nerozumím problému, jaká je spojitost mezi a a v?
"avavav".replace(/a/g, "e").replace(/v/g, "x"); // navrátí "exexex"
Marek88
Profil
Mělo by být funkční. Doporučuji ti, aby sis z toho udělal funkci...
    //var co= ["a", "b", "c", "x", "y", "z"];
    //var cim=["x", "y", "z", "a", "b", "c"];
    //EDIT: pokud jde jen o ty písmena, tak by šlo i:
    var co= "abcxyz";
    var cim="xyzabc";
        
    var vstup="aabbcc-duv-xyz... aaxxbbyycczz";
    var vystup="";
    for(var j=0; j<vstup.length; j++){
        for(var i=0; i<co.length; i++){
            if(vstup[j]==co[i]){
                vystup+=cim[i];
                break;
            }
        }
        if(i==co.length){
            vystup+=vstup[j];
        }
    }
    alert(vstup+"\n"+vystup);
High Voltage
Profil *
Když v je v tom poli více písmen, která se mají nahradit, a to prvni (napriklad a) se ma preměnit v (napriklad c), a (c) se má proměnit v (x), ale né to (c), které se proměnilo z (a)
Witiko
Profil
Marek88:
pokud jde jen o ty písmena, tak by šlo i
Nešlo, přístup k textovým řetězcům jako k polím není cross-browser podporovaný - například Internet Explorer si s ním rozumí až od osmičky.

High Voltage:
Tak to řeknu a ne že dám jako příklad zcela nesouvisející výměny. Pak bude asi skutečně potřeba použít cyklus - [#5] mi přijde příliš dlouhý a dvojité deklarace viz. 10. řádek scriptu nebo neustálé volání getteru length (řádky 9, 10, 16) se mi nelíbí a tak navrhnu svoji verzi, která dělá to samé s použitím jednoho cyklu o dvou řádcích:

var co = "abc",
    čím = "bcd",
    vstup = "abcabcabc",
    výstup = "",
    i2, znak;

for(var i1 = 0; znak = vstup.charAt(i1); i1++)
výstup += (i2 = co.indexOf(znak)) === -1?znak:čím[i2];

alert(výstup); // "bcdbcdbcd"

Druhou možností je netvořit výstup a psát rovnou do vstupu, ale pokud se nemýlím, tak jediná zaručeně funkční možnost editace je
vstup = vstup.substring(0, index) + písmeno + vstup.substring(index + 1); // Cross-browser alias k vstup[index] = písmeno;
Což je podle mě trochu přehnané, (edit) a zdá se i pomalejší.
Marek88
Profil
Witiko:
Nešlo, přístup k textovým řetězcům jako k polím není cross-browser podporovaný - například Internet Explorer si s ním rozumí až od osmičky.
Dík za info, to jsem nevěděl. Sice mě to napadlo, ale přiznám se, že jsem byl líný po tom pátrat.
Marek88
Profil
Witiko:
Samozřejmě uznávám, že tvoje řešení je rychlejší, ale přijede mi to trochu zbytečné. Pro text s deseti tisíci slovy (asi 40 stran textu - to je na web docela hodně) je můj čas 35 ms a tvůj 10ms. Ano, je to 3,5x rychlejší. Ale ani 35ms téměř nepostřehneš. (měřeno na mém ne moc výkonném PC)

Nejde mi o to, se hádat. Jen chci obhájit, že moje "funkce" není až tak špatná. Navíc je přehledná pro další použití (a případné úpravy) dalšími lidmi.
Witiko
Profil
Marek88:
O přehlednosti se právě podle mě nedá moc mluvit. Myslím, že každý bude radší případně upravovat dva krátké řádky místo deseti, které dělají to samé jen zbytečně složitě. Haj si svůj návrh jak chceš, ale nevyužít indexOf a místo toho procházet celé pole znaků cyklem mi přijde jako neuváženost. Přílišná složitost kódu poukazuje většinou na neznalost, umění je udělat zápis co nejjednodušší a nejčitelnější - ne naopak. :-)
Marek88
Profil
Witiko:
Takže chceš tvrdit, že funkce indexOf nemusí v nějakém cyklu procházet text, aby našla požadovaný znak? Jak by jinak to číslo vzala? Musí také projít řetězec nějakým cyklem a někam si ukládat hodnotu, u kterého písmenka právě je (obdoba proměnné "i" ve forcyklu).
Witiko
Profil
Marek88:
Takže chceš tvrdit
Nechci. Jistěže musí, ale jelikož je nativní, tak je na to optimalizovaná a může švindlovat. Chceš mi ty tvrdit, že je lepší opisovat funkcionalitu, která je v prohlížeči již vestavěná, vlastními konstrukcemi? Proč? Je to dlouhé, nepřehledné, pomalejší a výsledek je stejný. Skutečně mi teď nejde ani tak o rychlost jako o přehlednost kódu.

K té funkci indexOf bych ještě dodal, že i bez ní lze kód napsat v podstatně kompaktnější formě, než je vyobrazena v [#5]:
var co = "abc", 
    čím = "bcd", 
    vstup = "abcabcabc", 
    výstup = "", 
    i1, i2, znak1, znak2; 
 
hlavní:
for(i1 = 0; znak1 = vstup.charAt(i1); i1++) 
for(i2 = 0; znak2 = co.charAt(i2); i2++)
if(znak1 === znak2) {
  výstup += čím[i2];
  continue hlavní;
} výstup += znak1;
 
alert(výstup); // "bcdbcdbcd"
Marek88
Profil
Witiko:
Chceš mi ty tvrdit, že je lepší opisovat funkcionalitu, která je v prohlížeči již vestavěná, vlastními konstrukcemi
A to jsem řekl kde? Nevkládej mi slova do úst, prosím.

S tou přehledností to bude asi trochu individuální, protože podle mě [#5] a [#12] jsou přehledné asi tak stejně, ale [#7] podle mě ne.

Od začátku mi jde ale hlavně o to, že moje "funkce" v [#5] není tak špatná aby MUSELA být nahrazena tou tvojí dvouřádkovou (až na to přidání .charAt(i)). Z tvého příspěvku [#7] to, ale vypadá trochu jinak - např.: "neustálé volání getteru length (řádky 9, 10, 16) se mi nelíbí" - taková katastrofa to ale není. Ano, moje "funkce" je pomalejší, ale podle mě jí pro tento případ není potřeba jí optimalizovat, protože rozdíl je, jak jsem psal výše, zanedbatelný - to je jediné, o co mi šlo. Tím bych tuhle debatu rád ukončil...
Witiko
Profil
Marek88:
Nevkládej mi slova do úst, prosím.
Nápodobně. - Viz. [#11]

bude asi trochu individuální
[#7] podle mě ne
Osobně bych spíš řekl, že to bude mít něco do činění se znalostí jazyka a zkušenostmi s tvorbou algoritmů, ale budiž.

... dlouhá obhajoba vlastní funkce ... Tím bych tuhle debatu rád ukončil...
Já také, jsme trochu mimo topic. Jen nechápu Tvojí potřebu svojí funkci hájit. Sám musíš vidět, že je méně přehledná, než být může, a že je neoptimální. Funkci si tipuji napsal z hlavy na místě a proto na tom není nic neobvyklého. Já bych místo hádání se byl kupříkladu rád, že zde vidím na svojí tvorbu reakci, na základě které se můžu zdokonalit.
Chamurappi
Profil
Reaguji na Marka88:
Pro text s deseti tisíci slovy (asi 40 stran textu - to je na web docela hodně) je můj čas 35 ms a tvůj 10ms. Ano, je to 3,5x rychlejší. Ale ani 35ms téměř nepostřehneš.
Nebylo řečeno, k čemu ten skript potřebuje, ani jestli bude běžet v prohlížeči, takže nevíme, jestli si můžeme dovolit mrhat výkonem.

Od začátku mi jde ale hlavně o to, že moje "funkce" v [#5] není tak špatná
Je sice dobré neupínat se k předčasné optimalizaci, ale to neznamená, že rezignujeme na jakoukoliv optimalizaci. Horší funkce je horší. Což neznamená, že se nehodí jako mezikrok při hledání lepší.
Witikova dvojřádková funkce by šla přepsat do názornější podoby bez výrazného vlivu na výkon.


Reaguji na Witika:
Předpokládám, že replace s regulárním výrazem /[abc]/g a funkcí vracející {"a":"x", "b": "y", "c": "z"}[match] bude ještě pomalejší. Na pár místech to spokojeně používám :-)
Witiko
Profil
Chamurappi:
Však proč ne. Jednou z idejí vyšších jazyků je koneckonců i právě přehlednost nad výkonem. Mě ale přišla Markova88 funkce jak nepřehledná, tak zbytečně nevýkonná, což už si říká o nalezení lepšího řešení. :-)

Witikova dvojřádková funkce by šla přepsat
Už jsem tak myslím učinil v [#12].

bude ještě pomalejší
Jj, bude (edit: Na IE nerozhodně). Ale po stránce čitelnosti a názornosti jde o mého nového favorita.

Vaše odpověď

Mohlo by se hodit

Neumíte-li správně určit příčinu chyby, vkládejte odkazy na živé ukázky.
Užíváte-li nějakou cizí knihovnu, ukažte odpovídajícím, kde jste ji vzali.

Užitečné odkazy:

Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0