<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ebene7 &#187; Sortierung</title>
	<atom:link href="http://blog.ebene7.com/schlagwort/sortierung/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.ebene7.com</link>
	<description></description>
	<lastBuildDate>Tue, 04 Jun 2013 18:57:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Sortieren mit PHP5 Closures und dem Java Comparator Pattern</title>
		<link>https://blog.ebene7.com/2012/08/31/sortieren-mit-php5-closures-und-dem-java-comparator-pattern/</link>
		<comments>https://blog.ebene7.com/2012/08/31/sortieren-mit-php5-closures-und-dem-java-comparator-pattern/#comments</comments>
		<pubDate>Fri, 31 Aug 2012 04:00:13 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Callback]]></category>
		<category><![CDATA[Closure]]></category>
		<category><![CDATA[Comparator]]></category>
		<category><![CDATA[Interface]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Sortierung]]></category>

		<guid isPermaLink="false">http://blog.ebene7.com/?p=3421</guid>
		<description><![CDATA[Was mich schon oft bei PHP ein wenig störte ist, dass es zum Sortieren nicht so schöne Comparatoren wie in Java gibt. Nun habe ich in der Vergangenheit ja schon das eine oder andere über Closures in PHP und Java &#8230; <a href="https://blog.ebene7.com/2012/08/31/sortieren-mit-php5-closures-und-dem-java-comparator-pattern/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Was mich schon oft bei PHP ein wenig störte ist, dass es zum Sortieren nicht so schöne Comparatoren wie in Java gibt.</p>
<p>Nun habe ich in der Vergangenheit ja schon das eine oder andere über <a href="http://blog.ebene7.com/2012/01/30/closures-in-php/">Closures in PHP</a> und <a href="http://blog.ebene7.com/2010/09/06/besser-sortieren-mit-php-dank-java-interfaces/">Java Comparatoren für PHP</a> geschrieben und wollte das nun mal zusammenbringen.</p>
<p><span id="more-3421"></span>Einige PHP-Sortierfunktionen erlauben Callbacks, um die Reihenfolge zu bestimmen. Da ich das Ganze aber gerne in gut testbaren OOP-Einheiten hätte, müssen wir einen kleinen Umweg gehen.</p>
<p>Zunächst das obligatorische Interface.</p>
<pre>namespace E7;

interface Comparator {
  public function compare($a, $b);
}</pre>
<p>Diese Schnittstelle implementieren wir mit einer abstrakten Klasse.</p>
<pre>namespace E7;

class BaseComparator implements Comparator {
  public function compare($a, $b) {
    if ($a == $b) { return 0; }
    return $a &lt; $b ? -1 : 1;
  }

  public function __invoke() {
    return call_user_func_array(array($this, 'compare'), func_get_args());
  }
}</pre>
<p>Und schon haben wir einen einfachen, und zugegebenermaßen nicht typsicheren, Comparator.</p>
<p>Durch die magische Methode __invoke() kann ein Objekt nun wie eine Callbackfunktion verwendet werden.</p>
<p>Für die Sortierung von Objekten kann das dann einfach erweitert werden.</p>
<pre>class PersonComparator extends BaseComparator {
  public function compare($a, $b) {
    // hier Prüfung auf Typ etc.
    return parent::compare($a-&gt;getId(), $b-&gt;getId());
  }    
}</pre>
<p>Um die Sortierreihenfolge negieren zu können, können wir einen einfachen Wrapper nutzen.</p>
<pre>class ReverseOrder implements Comparator {
  private $_comparator;

  public function __construct(Comparator $comparator) {
    $this-&gt;_comparator = $comparator;
  }

  public function compare($a, $b) {
    return $this-&gt;_comparator-&gt;compare($a, $b) * -1;
  }
}</pre>
<p>Beispiel&#8230;</p>
<pre>//--
$people = array();
for ($i = 0; $i &lt; 10; $i ++) {
  $people[] = new Person();
}

echo 'BEFORE&lt;br/&gt;';
foreach($people as $person) {
  echo "$person&lt;br/&gt;";
}

$comparator = new ReverseOrder( new PersonComparator() );

uasort($people, function($a, $b) use ($comparator) {
    return $comparator-&gt;compare($a, $b);
});

// oder

uasort($people, $comparator);

echo 'AFTER&lt;br/&gt;';
foreach($people as $person) {
  echo "$person&lt;br/&gt;";
}</pre>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.ebene7.com/2012/08/31/sortieren-mit-php5-closures-und-dem-java-comparator-pattern/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Besser Sortieren mit PHP dank Java Interfaces</title>
		<link>https://blog.ebene7.com/2010/09/06/besser-sortieren-mit-php-dank-java-interfaces/</link>
		<comments>https://blog.ebene7.com/2010/09/06/besser-sortieren-mit-php-dank-java-interfaces/#comments</comments>
		<pubDate>Mon, 06 Sep 2010 05:00:46 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Dekorierer]]></category>
		<category><![CDATA[Entwurfsmuster]]></category>
		<category><![CDATA[Interface]]></category>
		<category><![CDATA[OOP]]></category>
		<category><![CDATA[Sortierung]]></category>

		<guid isPermaLink="false">http://blog.ebene7.com/?p=1344</guid>
		<description><![CDATA[PHP und Java haben aus meiner Sicht vieles gemeinsam, sei es nun die ähnliche Syntax oder der zu unrecht schlechte Ruf beider Sprachen. Spätestens jedoch wenn es um die Sortierung von beliebigen Objekten geht zeigt sich deutlich, dass Java die &#8230; <a href="https://blog.ebene7.com/2010/09/06/besser-sortieren-mit-php-dank-java-interfaces/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>PHP und Java haben aus meiner Sicht vieles gemeinsam, sei es nun die ähnliche Syntax oder der zu unrecht schlechte Ruf beider Sprachen. Spätestens jedoch wenn es um die Sortierung von beliebigen Objekten geht zeigt sich deutlich, dass Java die Nase vorn hat.</p>
<p>Ein Grund mehr mal über den PHP-Tellerrand zu spicken und einen kleine Ausflug in die Java-Welt zu machen.<span id="more-1344"></span></p>
<p>PHP bietet zwar mit diversen Array-Funktionen schon einige Möglichkeiten der Sortierung an, diese sind aber doch recht starr und man stößt schnell an gewisse Grenzen, wenn man mehr als nur einfache Datentypen sortieren will, da sowohl die Sortierlogik, wie auch der Vergleich der Objekte sind nach außen in einer Funktion zusammengefasst sind.</p>
<p>Wie funktioniert das denn nun in der Java-Welt? In Java müssen Objekte durch das Interface &#8220;Comparable&#8221; als sortierbar gekennzeichnet werden. Die meisten Standardklassen implementieren das bereits.</p>
<p>Das Interface schreibt die Methode &#8216;compareTo&#8221; vor, die es dem Objekt erlaubt, sich mit anderen Objekten zu vergleichen. Der Rückgabewert kann 1, 0 oder -1 sein.</p>
<p>Dazu ein kleines Beispiel:</p>
<p>Leider gibt ist in der SPL noch kein derartiges Interface vorhanden, also schreibe ich es einfach mal selbst.</p>
<pre>&lt;?php
interface Custom_Compareable
{
  public function compareTo($object);
}</pre>
<p>Dann brauchen wir noch ein Objekt zum Vergleichen.</p>
<pre>&lt;?php
class Person implements Custom_Comparable
{
  private $_id;
  private $_vorname;
  private $_nachname;
  private $_geburtsdatum;

  public function __construct($id)
  {
    $this-&gt;_id = $id;
  }

  //  Getter und Setter...

  public function compareTo($object)
  {
    if (!$object instanceof Person) {
      throw new InvalidArgumentException();
    }

    if ($this-&gt;_id &lt; $object-&gt;_id) {
      return -1;
    } else if ($this-&gt;_id == $object-&gt;_id) {
      return 0;
    } else {
      return 1;
    }
  }
}</pre>
<p>Damit können nun Objekte vom Typ Person standardmäßig nach ihrer Id unabhängig vom Suchalgorithmus sortiert werden.</p>
<pre>&lt;?php
$p1 = new Person(3);
$p2 = new Person(2);

if ($p1-&gt;compareTo($p2) &lt; 0) {
  // swap($p1, $p2)
}</pre>
<p>Bis jetzt haben wir zwar schon die Sortierlogik vom Vergleich der Objekte lösen können, aber trotzdem noch nicht viel gewonnen, da nur die Ids verglichen werden. Für abweichende Sortierungen lässt sich der Vergleich nun auch noch vom Personen-Objekt lösen. Dafür bietet Java das Interface &#8220;Comparator&#8221; an, bei uns wird es nun das Custom_Comparator-Interface.</p>
<pre>&lt;?php
interface Custom_Comparator
{
  public function compare($object1, $object2);
}</pre>
<p>Die Methode &#8220;compare()&#8221; hat die gleichen Rückgabewerte wie &#8220;compareTo()&#8221; und kann dadurch genauso verwendet werden.</p>
<pre>&lt;?php
class PersonComparatorVorname implements Custom_Comparator
{
  public function compare($object1, $object2)
  {
    if (!$object1 instanceof Person || !$object2 instanceof Person) {
      throw new InvalidArgumentException();
    }

    if ($object1-&gt;getVorname() &lt; $object2-&gt;getVorname()) {
      return -1;
    } else if ($object1-&gt;getVorname() == $object2-&gt;getVorname()) {
      return 0;
    } else {
      return 1;
    }
  }
}</pre>
<p>Durch diese beiden Interfaces haben wir nun die Möglichkeit, unsere Objekte beliebig sortieren zu lassen. Über die Wertigkeit der Objekte entscheidet nun das Objekt selbst, bzw. ein passender Comparartor. Wie die Objekte letztendlich sortiert werden ist egal, da die Logik an einer anderen Stelle implementiert wird und nun für alle Objekte gleich funktioniert, wenn diese &#8220;Comparable&#8221; sind.</p>
<pre>&lt;?php
$listeMitPersonen = array(new Person(1), new Person(2));
$comparator = new PersonComparatorVorname();

// die Funktionen stehen als Pseudocode
bubblesort($listeMitPersonen);
bubblesort($listeMitPersonen, $comparator);

quicksort($listeMitPersonen);
quicksort($listeMitPersonen, $comparator);</pre>
<p>Und auch die Logik für auf- oder absteigende Reihenfolge lässt sich komplett getrennt dank Dekorator-Pattern auslagern.</p>
<pre>&lt;?php
class ReverseComparator implements Custom_Comparator
{
  private $_comparator;

  public function __construct(Custom_Comparator $comparator)
  {
    $this-&gt;_comparator = $comparator;
  }

  public function compare($object1, $object2)
  {
    return $this-&gt;_comparator-&gt;compare($object1, $object2) * (-1);
  }
}</pre>
]]></content:encoded>
			<wfw:commentRss>https://blog.ebene7.com/2010/09/06/besser-sortieren-mit-php-dank-java-interfaces/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>CSV-Datei sortieren ganz einfach</title>
		<link>https://blog.ebene7.com/2010/07/28/csv-datei-sortieren-ganz-einfach/</link>
		<comments>https://blog.ebene7.com/2010/07/28/csv-datei-sortieren-ganz-einfach/#comments</comments>
		<pubDate>Wed, 28 Jul 2010 18:15:32 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Grundlagen]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Snippets]]></category>
		<category><![CDATA[Array]]></category>
		<category><![CDATA[CSV]]></category>
		<category><![CDATA[Sortierung]]></category>

		<guid isPermaLink="false">http://blog.ebene7.com/?p=1160</guid>
		<description><![CDATA[Heute hatte ich im Büro ein lustiges Gespräch darüber, wie einfach es ist eine CSV-Datei alphabetisch zu sortieren und dass das passende Script als inline (also alles in einer Zeile) in unter zehn Minuten geschrieben ist. Zeitlich war das wie &#8230; <a href="https://blog.ebene7.com/2010/07/28/csv-datei-sortieren-ganz-einfach/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Heute hatte ich im Büro ein lustiges Gespräch darüber, wie einfach es ist eine CSV-Datei alphabetisch zu sortieren und dass das passende Script als inline (also alles in einer Zeile) in unter zehn Minuten geschrieben ist.<span id="more-1160"></span></p>
<p>Zeitlich war das wie erwartet locker drin, nur leider klappte das mit dem Inline aufgrund der Funktion sort() nicht, da diese das zu sortierende Array als Referenz verarbeitet.</p>
<p>Kleine Spielerei aber vielleicht braucht ja mal jemand den Schipsel.</p>
<pre><code>&lt;?php
$file = 'pfad/zur/datei.csv';
$lines = file($file);
sort($lines);
file_put_contents($file, implode('', $lines));</code></pre>
<p>Einmal ausgeführt und aus</p>
<pre><code>"test","test"
"bla","blubber"
"apfel","apfel"</code></pre>
<p>wird</p>
<pre><code>"apfel","apfel"
"bla","blubber"
"test","test"</code></pre>
]]></content:encoded>
			<wfw:commentRss>https://blog.ebene7.com/2010/07/28/csv-datei-sortieren-ganz-einfach/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
