Autor Zpráva
10messi10
Profil *
Zdravím, potřeboval bych poradit problém je v tomhle: v textarea bude třeba
25-rohlik
30-chleba
80-houska
a chtěl bych aby se sečetly čísla před pomlčkou :D

Předem díky za pomoc :)

Moderátor Chamurappi: Titulek „matematické operacfe“ nevystihoval podstatu dotazu. Příště zkus prosím vymyslet lepší.
Joker
Profil
10messi10:
Asi by bylo lepší to rozdělit na dva <input>y (číslo a popis) a pak jednoduše sečíst čísla. Bude to tak jednodušší a odolnější vůči chybám.
10messi10
Profil *
To tak právě mám, chtěl jsem zkusit pomocí toho 2. způsobu, nešlo by to nějak?
Jan Tvrdík
Profil
10messi10:
Šlo, buď pomocí regulárních výrazů nebo jednodušeji pomocí explode.
10messi10
Profil *
Prosím Vás neměl by jste příklad jak by to mohlo pomocí toho vypadat? :)
juriad
Profil
10messi10:
$text = "25-rohlik
30-chleba
80-houska";

$sum = 0;
$lines = explode("\n", $text);
foreach($lines as $line) {
        # toto udělej lépe, nebo budeš hodně brzy překvapený, že to nefunguje :-)
        $sum += intval($line);
}
echo $sum;
10messi10
Profil *
juriad:
Funguje díky moc, ještě jedna věc. Když třeba chleba bude mít hodnotu 27,50Kč a bude jich tam deset tak jak přidat cenu třeba tomu chlebu, rohlíkům a houskám?
mimochodec
Profil
10messi10:
jak přidat cenu třeba tomu chlebu, rohlíkům a houskám?

Dovolím si použít juriadův kód:

$lines = explode("\n", $text);
foreach($lines as $line) {
    list ($price, $item) = explode("-", $line);  //  v $price, $item je cena a název jednotlivé položky
}
10messi10
Profil *
Nevíte proč to nefunguje? :(
$lines = explode("\n", $text);
foreach($lines as $line) {
    list ("27,50", "Chleba") = explode("-", $line);  //  v $price, $item je cena a název jednotlivé položky
$sum *= intval($line);
}
echo $sum;
mimochodec
Profil
10messi10:
Nevíte proč to nefunguje? :(

Víme. Funkci list používáš špatně. Klikni na ni, dozvíš se víc.
anonymníí
Profil *
10messi10:
Nefunguje to, neboť je to rozbité :-)

1. Desetinná čísla se v PHP píší s desetinnou tečkou, nikoliv čárkou.

2. Nevím, jak jsi přišel na toto použití list, když je výše použita správně

3. Pokud nepotřebuješ pracovat s názvem produktu, což z 1) vypadá, že nepotřebuješ, bude rychlejší získávat cenu pomocí funkcí substr a strpos. Pokud se ti ale do budoucna může název produktu hodit, pracuj s listem.

4. *=: Myslím, že chceš přičítat, ne násobit...

5. "27,50": Přestože tady je to skutečně string, pracuj s čísly jako s čísly, tedy bez uvozovek a s desetinnou tečkou.
mimochodec
Profil
anonymníí:
bude rychlejší získávat cenu pomocí funkcí substr a strpos.


<?php

$arr = array();

for ($i = 1; $i <= 100000; $i++) {
  $arr [] = rand ( 0, 9999)."-".rand ( 0, 9999);
}

$time_start = microtime(true);

for ($i = 1; $i <= 10; $i++) {
  foreach($arr as $line) {
    list ($prvni, $druha) = explode("-", $line);
  }
}

$time_end = microtime(true);

echo ($time_end - $time_start)."<br>";  

// ---------------------------------

$time_start = microtime(true);

for ($i = 1; $i <= 10; $i++) {
  foreach($arr as $line) {
//    $prvni = substr(line, 0, $pos);
    $druha = substr($line, strpos($line, "-")+1);
  }
}

$time_end = microtime(true);

echo ($time_end - $time_start);  

?>

Naměřil jsem
0.73163914680481
1.354367017746

Explode je rychlejší než strpos, substr.
V případě, že by se měla získávat i ta první část, dělaly ty časy kolem 2,5 s.


Byla tam chyba. Po opravě jsou časy:
0.71856999397278
0.68227100372314
anonymníí
Profil *
mimochodec:
A tu syntaktickou chybu sis zanesl jen sem na diskusi? :-)

Explode je rychlejší než strpos, substr
A teď zkus pracovat bez meziproměnné, která to trochu zpomaluje.
mimochodec
Profil
Dobrá poznámka. Bez meziproměnné $pos:
0.71480512619019
1.2623798847198

Syntaktickou chybu nevidím.
juriad
Profil
mimochodec:
29. řádek - line

anonymníí:
A není to syntaktická chyba, ale vlastnost PHP.
mimochodec
Profil
juriad:
Sakra! Dík! To mění situaci:

0.71856999397278
0.68227100372314
Opravím ten dlouhý příspěvek.
anonymníí
Profil *
juriad:
A není to syntaktická chyba, ale vlastnost PHP.
Ano, je to vlastnost, ale v kontextu příspěvku výše se jednalo o chybu. Asi jsem ji nesprávně nazval syntaktickou.

mimochodec:
Čiliže? Že by vynechání meziproměnné a používání proměnných namísto nedefinovaných konstant bylo rychlejší? Je to logické, při explodu vytváříš nejprve pole, z kterého pak něco vybíráš. Se substrem jen rovnou zahodíš kus stringu. Přiznávám, že mě takhle vedla intuice, neměřil jsem to. Upřímně jsem očekával, že rozdíl bude větší než (+-4-5%).
mimochodec
Profil
anonymníí:
Potřebuješ poplácat po rameni? Ano, tvůj postup je o chlup rychlejší. Pokud 10messi10 potřebuje jen součet, může ho použít a při počtu kolem miliónu položek opravdu skoro 40 milisekund ušetří.
anonymníí
Profil *
mimochodec:
Nee, nepotřebuji poplácat. Jen jsem ti chtěl (proto to vysvětlení, proč jsem předpokládal) ukázat, že někdy stačí selský rozum a dvojnásobně strávený čas při vykonávání této jednoduché operace byl nesmyslný.
Joker
Profil
Já jen podotknu, že stejně jako v době [#2] se mi pořád zdá náchylné k chybám a vůbec hloupé všechno nacpat do jednoho políčka a pak se snažit to zase rozdělit.
juriad
Profil
anonymníí:
Nezapomínej na to, že všechny ty funkce jsou implementovány v C a liší se jen nepatrně. To, že musíš skrz prtavý řetězec projít dvakrát (ehm), se třeba zaplatí aloakcí pole, které explode musí vrátit.

Obecně si stále myslím, že nemá smysl řešit výkonnost jednotlivých funkcí při programování v PHP. Je mnohem levnější koupit výkonnější server než kvalitnějšího programátora, který zná i detaily vnitřní implementace PHP.

Ale zpět 10messi10mu:
Pokud to chápu správně, tak někde chce mít uložené ceny a ta čísla před pomlčkou jsou počty kusů.

$text = "25-rohlik
30-chleba
80-houska";

$prices = array('rohlik' => 2.5, 'chleba' => 27.5, 'houska' => 5);

$sum = 0;
$lines = explode("\n", $text);
foreach($lines as $line) {
        $parts = explode('-', $line, 2);
        if (count($parts) != 2) {
                die("Line without dash: " . $line);
        }
        $count = floatVal($parts[0]);
        $what = trim($parts[1]);

        if (!isset($prices[$what])) {
                die("Unknown product: " . $what);
        }

        $sum += $count * $prices[$what];
}
echo $sum;
mimochodec
Profil
anonymníí:
Jen jsem ti chtěl (proto to vysvětlení, proč jsem předpokládal) ukázat, že někdy stačí selský rozum a dvojnásobně strávený čas při vykonávání této jednoduché operace byl nesmyslný.

Napsaný kód obecně lze hodnotit pomocí různých kritérií. Ty preferuješ "selský rozum", já maximální přehlednost. Tu rychlost jsem otestoval spíš ze zvědavosti, svůj účel to splnilo. Nevím, kde vidíš dvojnásobný čas, já kdybych toto řešil, bych s dovolením zůstal u explode.
10messi10
Profil *
Děkuji, funguje tak jak jsem si představoval :)

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

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