Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: Off Topic - alphabetische Ordnung

2 views
Skip to first unread message

Sebastian Suchanek

unread,
Feb 21, 2015, 7:22:15 AM2/21/15
to
Thus spoke Sigbert Helle:

[Fullquote wegen f'up]

> was deutschsprachiges zum Thema php gibt's ja wohl nicht im
> Usenet, oder?

Was gefällt Dir an de.comp.lang.php nicht?
Ich leite mal um...

> Vielleicht mag mir hier jemand helfen ...
> Ich will aus einer MySQL-DaBa eine Liste mit Personen
> auslesen und sie dann auf einer Webseite so darstellen:
>
> A
> Franz Anton
> Bernd Atze
> .
> .
> .
> B
> Karl Bernd
>
> Also vor jedem neuen Buchstaben diesen selbst darstellen.
> Das einzige, was mir einfällt ist, jeden der 26 (oder mehr)
> Anfangsbuchstaben einzeln auslesen.
> Aber da muss es doch was einfacheres geben, oder?
>
> Vielen Dank schon mal!

Tschüs,

Sebastian

PS: XP & f'up2 de.comp.lang.php
--
X-Post, FollowUp-To de.comp.lang.php

Thomas 'PointedEars' Lahn

unread,
Feb 21, 2015, 11:08:13 AM2/21/15
to
[F'up2 de.comp.datenbanken.mysql]

Sebastian Suchanek wrote:

> Thus spoke Sigbert Helle:
>> Vielleicht mag mir hier jemand helfen ...
>> Ich will aus einer MySQL-DaBa eine Liste mit Personen

Die übliche(re) Abkürzung für Datenbank ist „DB“.

>> auslesen und sie dann auf einer Webseite so darstellen:
>>
>> A
>> Franz Anton
>> Bernd Atze

Weshalb soll „Bernd Atze“ vor „Karl Bernd“ sortiert werden?
Was ist hier Vor-, was Nachname?

>> .
>> .
>> .
>> B
>> Karl Bernd
>>
>> Also vor jedem neuen Buchstaben diesen selbst darstellen.

Was ist ein „neuer Buchstabe“ in diesem Sortierschema?

>> Das einzige, was mir einfällt ist, jeden der 26 (oder mehr)
>> Anfangsbuchstaben einzeln auslesen.

MySQL unterstützt die Sortierung von Datensätzen (wie das geht, ist nicht
hier, sondern in de.comp.datenbanken.mysql on-topic – die Umleitung der
Diskussion nach de.comp.lang.php war voreilig). Falls die Sortierung nicht
ohne weiteren Datenbankzugriff geändert werden muss, schlage ich vor, diese
nicht in PHP zu machen, auch wenn es möglich wäre.

>> Aber da muss es doch was einfacheres geben, oder?

Ja. Wie sieht Dein Ansatz und wie sehen Deine Lösungsversuche im
*Quelltext* aus?

>> Vielen Dank schon mal!

Bitte.

<http://www.tty1.net/smart-questions_de.html>

--
PointedEars
Zend Certified PHP Engineer
Twitter: @PointedEars2
Please do not cc me. / Bitte keine Kopien per E-Mail.

Sigbert Helle

unread,
Feb 21, 2015, 11:47:30 AM2/21/15
to
Am 21.02.2015 um 17:06 schrieb Thomas 'PointedEars' Lahn:

> Was ist hier Vor-, was Nachname?
Vorne steht der Vorname, danach kommt der Nachname ...

> Was ist ein „neuer Buchstabe“ in diesem Sortierschema?
Wenn alle Nachnamen mit A genannt sind, soll als (vor allem optische)
Einteilung der Buchstabe B erscheinen.

> Ja. Wie sieht Dein Ansatz und wie sehen Deine Lösungsversuche im
> *Quelltext* aus?
Na ja so etwa:

$q = "SELECT Vorname, Nachname FROM ".tblLeute." ORDER BY Nachname";
und dann das übliche:
$result = mysql_query($q);
$number = mysql_numrows($result);
$row = mysql_fetch_array($result);
$Vorname = $row[Vorname];
$Nachname ...

print $Vorname." ".$Nachname;

Und vorher müsste ich jetzt mit einer WHERE-Klausel 26 mal den
jeweiligen Anfangsbuchstaben nehmen.

print "A";
print $Vorname." ".$Nachname;
...
print "B";
print $Vorname." ".$Nachname;



Falls da nicht jemand eine nette Vereinfachungsidee hat, werde ich das
auch so machen.

Gruß
Sigbert




Sigbert Helle

unread,
Feb 21, 2015, 12:14:00 PM2/21/15
to
Hallo Leute,

'tschuldigung- hab's beim Googeln doch grad gefunden:

for ( $a="a" ; strlen($a) < 2 ; $a++) {
echo "$a<br>";
}

Wusste nicht, dass man auch Schleifen mit Buchstaben durchlaufen kann.

Gruß
Sigbert

Markus Heinz

unread,
Feb 21, 2015, 12:41:54 PM2/21/15
to
Hallo.
Ich würde wie folgt vorgehen:

1. Einen SQL Query ausführen, der alle Namen in der passenden Sortierung
liefert.
2. Alle Namen in einer Schleife ausgeben, wobei aus dem Nachnamen der
erste Buchstabe extrahiert wird. Ist dieser Buchstabe ungleich dem
zuletzt extrahierten Buchstaben, wird er in einer Zeile vor dem Namen
ausgegeben.

Vorteile:

- Es wird nur einer anstatt 26 Queries durchgeführt.
- Es werden nur die Buchstaben ausgegeben, zu denen auch Namen vorhanden
sind (kann auch als Nachteil gesehen werden, wenn die Anforderungen
anders sind)

Grüße

Markus Heinz



Thomas 'PointedEars' Lahn

unread,
Feb 21, 2015, 1:11:08 PM2/21/15
to
Sigbert Helle wrote:

> Am 21.02.2015 um 17:06 schrieb Thomas 'PointedEars' Lahn:
>> Was ist hier Vor-, was Nachname?
> Vorne steht der Vorname, danach kommt der Nachname ...

Dann ist Dein Beispiel fhcsal sortiert.

>> Ja. Wie sieht Dein Ansatz und wie sehen Deine Lösungsversuche im
>> *Quelltext* aus?
> Na ja so etwa:
>
> $q = "SELECT Vorname, Nachname FROM ".tblLeute." ORDER BY Nachname";
> und dann das übliche:
> $result = mysql_query($q);
> $number = mysql_numrows($result);
> $row = mysql_fetch_array($result);
> $Vorname = $row[Vorname];
> $Nachname ...

Die mysql_*-Funktionen aus der mysql-Erweiterung sind veraltet und sollten
nicht mehr verwendet werden. Stattdessen solltest Du mysqli oder PDO_mysql
verwenden (ich empfehle Letzteres, auch da PDO aufgrund der grundsätzlich
DB-unabhängigen Schnittstelle den späteren Wechsel zu einem anderen DBMS
erleichtert):

<http://php.net/mysql_query>
<http://php.net/mysql_num_rows>
<http://php.net/mysql_fetch_array>
<http://php.net/manual/en/mysqlinfo.api.choosing.php>

> print $Vorname." ".$Nachname;
>
> Und vorher müsste ich jetzt mit einer WHERE-Klausel 26 mal den
> jeweiligen Anfangsbuchstaben nehmen.
>
> print "A";
> print $Vorname." ".$Nachname;
> ...
> print "B";
> print $Vorname." ".$Nachname;
>
>
>
> Falls da nicht jemand eine nette Vereinfachungsidee hat, werde ich das
> auch so machen.

Erstens solltest Du es vermeiden, “print” oder “echo” nacheinander
auszuführen. Für so etwas gibt es implode(), ausserdem Templates.

Zweitens reicht “print” nicht aus: “print” generiert nicht automatisch einen
Zeilenumbruch (“echo” auch nicht).

Drittens ist es nicht sinnvoll, für jeden Buchstaben eine separate Abfrage
auszuführen. Führ *eine* Abfrage aus und sortier das Ergebnis nach Nachname
(das kann schon MySQL). Darüber kannst Du in PHP iterieren und den
Anfangsbuchstaben nur dann generieren, wenn er sich beim Nachnamen im
Vergleich zum vorhergehenden Eintrag ändert (so mache ich das bisher, jedoch
nicht für Nachnamen [1]).

Viertens könntest Du, wenn Du ein vorsortiertes Array aus Datensätzen hast,
dieses nach Anfangsbuchstaben zusammenfassen:

$ php -r '

$names = [
["name" => "alois"],
["name" => "anton"],
["name" => "barbara"],
["name" => "berta"]
];

$names_by_letter = [];

array_walk($names,
function ($e) use (&$names_by_letter) {
$letter = $e["name"][0];
$names_by_letter[$letter][] = $e;
});

print_r($names_by_letter);'
Array
(
[a] => Array
(
[0] => Array
(
[name] => alois
)

[1] => Array
(
[name] => anton
)

)

[b] => Array
(
[0] => Array
(
[name] => barbara
)

[1] => Array
(
[name] => berta
)

)

)

Siehe <http://php.net/array_walk> (Du kannst stattdessen auch eine for- oder
foreach-Schleife verwenden; die array_*-Funktionen sind eleganter, aber
nicht notwendigerweise effizienter). Dann kannst Du über dieses Array (mit
“foreach”) iterieren bzw. es mit “echo implode('…', array_map(…, …));”
geeignet ausgeben.

Der Ansatz, Einträge nach Anfangsbuchstaben zusammenzufassen, verhindert bei
einer Index-Darstellung, die nicht gleichzeitig die Einträge ausgeben soll,
dass die Index-Darstellung Angaben für nicht existierende Einträge enthält.
(Deshalb werde ich den ab sofort für alphanumerische Verzeichnisse
verwenden.) Ebenso kann er die Suche in den Daten beschleunigen (auf diese
Weise lässt sich ein nach Buchstaben indizierter Suchbaum erstellen).

HTH

______
[1] <http://PointedEars.de/es-matrix#features-table>

Christoph M. Becker

unread,
Feb 21, 2015, 1:23:30 PM2/21/15
to
Sigbert Helle schrieb:

> 'tschuldigung- hab's beim Googeln doch grad gefunden:
>
> for ( $a="a" ; strlen($a) < 2 ; $a++) {
> echo "$a<br>";
> }
>
> Wusste nicht, dass man auch Schleifen mit Buchstaben durchlaufen kann.

Es geht hier nicht so sehr um die Schleife an sich, sondern um das
Verhalten des Post-Inkrement-Operators bei String-Werten. Bei aktuellen
PHP-Versionen sollte Dein Code wie gewünscht funktionieren, aber ich
wäre mir nicht sicher, ob sich das nicht mal ändert. Es gibt ein RFC,
das vorschlägt Inkrement-Operatoren auf String-Werten zu deprecaten[1].
Besonders kritisch finde ich aber die Abbruchbedingung, allein schon
weil die schwer zu verstehen ist -- ab welchem Zeichen wird denn der
String zweistellig? Ab dem kleinen "z", oder vielleicht erst bei "\x7F"
oder gar "\xFF" oder ...? Ich finde daher folgendes verständlicher:

for ($a = 'a'; $a <= 'z'; $a++)

Ich selbst würde wohl folgendes verwenden:

for ($i = ord('a'), $z = ord('z'); $i <= $z; $i++) {
echo chr($i) . '<br>';
}

PS: Was machst Du eigentlich mit Herrn *Ü*berflieger?

[1] <https://wiki.php.net/rfc/normalize_inc_dec>

--
Christoph M. Becker

Christoph M. Becker

unread,
Feb 21, 2015, 1:28:10 PM2/21/15
to
Thomas 'PointedEars' Lahn schrieb:

> Sigbert Helle wrote:
>
>> $q = "SELECT Vorname, Nachname FROM ".tblLeute." ORDER BY Nachname";
>> und dann das übliche:
>> $result = mysql_query($q);
>> $number = mysql_numrows($result);
>> $row = mysql_fetch_array($result);
>> $Vorname = $row[Vorname];
>> $Nachname ...
>
> Die mysql_*-Funktionen aus der mysql-Erweiterung sind veraltet und sollten
> nicht mehr verwendet werden. [...]

ACK, zumal ext/mysql nicht mehr mit PHP 7.0 gebündelt ausgeliefert
werden wird[1].

[1]
<https://wiki.php.net/rfc/remove_deprecated_functionality_in_php7#extmysql>

--
Christoph M. Becker

Sigbert Helle

unread,
Feb 21, 2015, 1:56:11 PM2/21/15
to
Vielen Dank erstmal für die Hinweise - da hab ich in den nächsten Tagen
einiges durchzuarbeiten!

Gruß
Sigbert Helle

Thomas Hochstein

unread,
Feb 26, 2015, 2:00:04 AM2/26/15
to
Sigbert Helle schrieb:

> Und vorher müsste ich jetzt mit einer WHERE-Klausel 26 mal den
> jeweiligen Anfangsbuchstaben nehmen.

Wieso? Du lässt Dir die Daten geordnet nach den Nachnamen ausgeben.
Dann gibst Du sie in einer Schleife nacheinander aus. (Soweit wohl der
bisherige Stand.)

Jetzt genügt es doch, den Anfangsbuchstaben des aktuellen Nachnamens
am Ende der Schleife zu speichern und beim nächsten Durchlauf zu
prüfen, ob der Anfangsbuchstabe des aktuellen Nachnamens identisch ist
und wenn nicht, vor der Ausgabe des Namens den neuen Anfangsbuchstaben
auszugeben.

Andere denkbare Möglichkeiten sind Dir ja auch bereits genannt worden.

Grüße,
-thh

Arno Welzel

unread,
Feb 26, 2015, 6:06:21 AM2/26/15
to
Am 2015-02-21 um 17:47 schrieb Sigbert Helle:
> Am 21.02.2015 um 17:06 schrieb Thomas 'PointedEars' Lahn:
>
>> Was ist hier Vor-, was Nachname?
> Vorne steht der Vorname, danach kommt der Nachname ...
>
>> Was ist ein „neuer Buchstabe“ in diesem Sortierschema?
> Wenn alle Nachnamen mit A genannt sind, soll als (vor allem optische)
> Einteilung der Buchstabe B erscheinen.
>
>> Ja. Wie sieht Dein Ansatz und wie sehen Deine Lösungsversuche im
>> *Quelltext* aus?
> Na ja so etwa:
>
> $q = "SELECT Vorname, Nachname FROM ".tblLeute." ORDER BY Nachname";
> und dann das übliche:
> $result = mysql_query($q);
> $number = mysql_numrows($result);
> $row = mysql_fetch_array($result);
> $Vorname = $row[Vorname];
> $Nachname ...
>
> print $Vorname." ".$Nachname;
>
> Und vorher müsste ich jetzt mit einer WHERE-Klausel 26 mal den
> jeweiligen Anfangsbuchstaben nehmen.

Ähm - nein.

Du kannst auch einfach alle Namen sortiert abfragen und Dir bei der
Ausgabe merken, welcher Buchstabe zuletzt benutzt wurde - und falls der
sich ändert, dann ändern.

Stark vereinfacht:

// "aktueller" Buchstabe noch leer
$letterCurrent = '';

while( ... ) {
// Neuen Buchstaben ermitteln
$letterNew = substr($name, 1);

// Wenn der neue Buchstabe vom "aktuellen" Buchstaben
// abweicht, dann uebernehmen und ausgeben
if($letterNew != $letterCurrent) {
$letterCurrent = $letterNew;
print $letterCurrent;
}

// Jetzt den Namen ausgeben
print $name.' '.$vorname;
}


Soweit klar?

--
Arno Welzel
http://arnowelzel.de
http://de-rec-fahrrad.de
http://fahrradzukunft.de
0 new messages