You are here:  » How do I sort parsed results on not shown fields?


How do I sort parsed results on not shown fields?

Submitted by MvdL1979 on Wed, 2014-04-02 10:56 in

Hi David,

Thought I would use the forum for once instead of bothering you always by email. Haha.

Sidenote; for the people who still haven't bought MagicParser and just reading the forums, just go buy it. Great piece of software with excellent support!

Anyways I am using the following piece of code on one of my websites:

<?php
  $items 
= array();
  
$exclude = array("MANNHEIM NECKAR","KOBLENZ UP","xxx","xxx","xxx","xxx","xxx","xxx","xxx",
"xxx","xxx","xxx","xxx","xxx","xxx","xxx","xxx");
  
$include = array("KONSTANZ","RHEINWEILER","BREISACH","KEHL","IFFEZHEIM",
"PLITTERSDORF","MAXAU","SPEYER","MANNHEIM","WORMS","NIERSTEIN","MAINZ",
"OESTRICH","BINGEN","KAUB","SANKT GOAR","BRAUBACH","KOBLENZ","NEUWIED",
"ANDERNACH","OBERWINTER","BONN","KÖLN","DÜSSELDORF","WESEL","REES","EMMERICH");
  function 
waterstanden_parse($item) {
    global 
$items;
    global 
$max;
    global 
$exclude;
    global 
$include;
    foreach(
$exclude as $word) {
      if (
stripos($item["PEGELNAME"],$word)!==FALSE) return;
    }
    
$items[] = $item;
  }
  function 
waterstanden_display($k,$item) {
    
$class = (($k 1)?"odd":"even");
    print 
"<div class='table_rowv2 ".$class."'><div class='ver_thv2'>".$item["PEGELNAME"]."</div> <div class='table_col3v2'>".$item["MESSWERT"]." cm</div></div>";
  }
  if (
$filename cacheFetch("{link saved}",3600)) {
    
MagicParser_parse($filename,"waterstanden_parse","xml|DATA/TABLE/GEWAESSER/ITEM/");
  }
  if (!
count($items)) {
    
// backup feed
    
$filename cacheFetch("{link saved}",3600);
    
MagicParser_parse($filename,"waterstanden_parse","xml|DATA/TABLE/GEWAESSER/ITEM/");
  }
  if (!
count($items)) {
    echo 
"<p class='pnieuws'>Waterstanden zijn op dit moment helaas niet beschikbaar.</p>";
    echo 
"<p class='pnieuws'>Over 10 minuten wordt een nieuwe poging ondernomen.</p>";
  }
  else {
    
$top_items = array();
    
$all_items = array();
    foreach(
$items as $k => $item)
    {
      foreach(
$include as $word) {
        if (
stripos($item["PEGELNAME"],$word)!==FALSE) {
          
$top_items[] = $item;
          continue;
        }
      }
      
$all_items[] = $item;
    }
    
$all_items array_merge($top_items,$all_items);
    
$max 27;
    foreach(
$all_items as $k => $item) {
      
waterstanden_display($k,$item);
      
$max--;
      if (!
$max) break;
    }
  }
?>

If you check the source: {link saved}
You will see it has several fields. One of them is called "KM". I don't display this one in the code above, because I only use "PEGELNAME" and "MESSWERT" on my website.

However is it possible to sort it anyways based on the "KM" value? Because it now outputs the results alphabetically (like from the source). I want it to be sorted by the value of "KM".

To give a better example; it currently outputs everything (based on the above code) like this:

ANDERNACH 171 cm
BINGEN 144 cm
BONN 209 cm
BRAUBACH 180 cm
BREISACH 200 cm
DÜSSELDORF 166 cm
EMMERICH 152 cm

But I want it to show it like this (based on the "KM" field):

BREISACH 180 cm (KM value is 227,55)
BINGEN 144 cm (KM value is 528,36)
BRAUBACH 180 cm (KM value is 579,98)
ANDERNACH 171 cm (KM value is 613,78)
BONN 209 cm (KM value is 654,80)
DÜSSELDORF 166 cm (KM value is 744,20)
EMMERICH 152 cm (KM value is 851,90)

As you can see above everything is sorted from the value of KM from low to high.

Thanks in advance!

Regards,
Michel

Submitted by support on Wed, 2014-04-02 11:22

Hi Michel,

Bear in mind that you are currently promoting selected results to the top, so I'm assuming you would like each sorted by KM, and then merged... This can be done with PHP's handy usort() function. Where you currently have this code:

  $all_items = array_merge($top_items,$all_items);

...REPLACE with:

  function cmp($a, $b)
  {
    $aa = floatval(str_replace(",",".",$a["KM"]));
    $bb = floatval(str_replace(",",".",$b["KM"]));
    if ($aa == $bb) {
        return 0;
    }
    return ($aa < $bb) ? -1 : 1;
  }
  usort($top_items,"cmp");
  usort($all_items,"cmp");
  $all_items = array_merge($top_items,$all_items);

Hope this helps!
Cheers,
David
--
MagicParser.com

Submitted by MvdL1979 on Wed, 2014-04-02 11:51

Thanks David!

It works perfectly. :)

Regards,
Michel

Submitted by MvdL1979 on Wed, 2014-04-02 12:19

I was looking at some of the code you have given me in the past and I also wanted to try to remove some of the excessive parts of the results.

For example I have two items which are shown like this:

KEHL-KRONENHOF
NIERSTEIN-OPPENHEIM
NEUWIED STADT

I want this cleaned to:

KEHL
NIERSTEIN
NEUWIED

I went through the previous pieces of code you have given me in the past and I know for certain I have to use the str_replace() function.

The stuff I found and altered it a bit was something like this:

<?php
    $found 
0;
    
$title $record["PEGELNAME"];
    
$title str_replace("-KRONENHOF"," ",$title);
    
$title str_replace("-OPPENHEIM"," ",$title);
    
$title str_replace(" STADT"," ",$title);
?>

However title isn't used in my current code. I then replaced $title with $items but that didn't work. The result shown on the page was completely empty.

Also everything is shown as uppercase (probably because the source is also like that). I just want the first letter to be a capital and the rest small letters. So instead of showing "KEHL" it should show "Kehl". I tried to do this the "easy" way by using CSS (text-transform:capitalize;) on it, but it simply ignores it.

Submitted by support on Wed, 2014-04-02 13:23

Hi Michel,

Following the above code you could then simply use $title in place of $record["PEGELNAME"], otherwise, you can simply work directly on $record["PEGELNAME"] e.g.

  $record["PEGELNAME"] = str_replace("-KRONENHOF"," ",$record["PEGELNAME"]);
  $record["PEGELNAME"] = str_replace("-OPPENHEIM"," ",$record["PEGELNAME"]);
  $record["PEGELNAME"] = str_replace(" STADT"," ",$record["PEGELNAME"]);

Hope this help!
Cheers,
David
--
MagicParser.com

Submitted by MvdL1979 on Wed, 2014-04-02 13:47

Thanks for the quick response back...

Well I added it (even on several spots), but it doesn't do anything as it seems (or it's ingoring ir)?

{code saved}

Also everything is shown as uppercase (probably because the source is also like that). I just want the first letter to be a capital and the rest small letters.

So instead of showing "KEHL" it should show "Kehl". I tried to do this the "easy" way by using CSS (text-transform:capitalize;) on it, but it simply ignores it.

Thanks once more.

Regards,
Michel

Submitted by support on Wed, 2014-04-02 13:54

Hi Michel,

Ah - all it is, is that your code is using $item instead of $record, so instead of the above, use the following code, to which i've also added a final line to the make it "Name Case" instead of all upper case:

$item["PEGELNAME"] = str_replace("-KRONENHOF"," ",$item["PEGELNAME"]);
$item["PEGELNAME"] = str_replace("-OPPENHEIM"," ",$item["PEGELNAME"]);
$item["PEGELNAME"] = str_replace(" STADT"," ",$item["PEGELNAME"]);
$item["PEGELNAME"] = ucwords(strtolower($item["PEGELNAME"]));

Cheers,
David
--
MagicParser.com

Submitted by MvdL1979 on Wed, 2014-04-02 14:55

Man I am sorry... I feel really stupid sometimes.
I seem to ignore the obvious and think of what I am doing wrong the difficult way. Sorry.

Well it works now (both). So thank you very much again.

Regards,
Michel

Submitted by MvdL1979 on Thu, 2014-04-03 08:01

Code is working excellent though one small, though cosmetic, problem.

Two places use an 'umlaut' in their names. These are:

- Köln
- Düsseldorf

For whatever the Ö and Ü don't get shrinked. So instead of showing 'Köln' and 'Düsseldorf' it shows 'KÖln' and 'DÜsseldorf'. The 'Ö' and 'Ü' stay as capital letters.

I did try several things like:

$item["PEGELNAME"] = str_replace("Ö","ö",$item["PEGELNAME"]);
$item["PEGELNAME"] = str_replace("Ü","ü",$item["PEGELNAME"]);

and

$item["PEGELNAME"] = str_replace("Ö","o",$item["PEGELNAME"]);
$item["PEGELNAME"] = str_replace("Ü","u",$item["PEGELNAME"]);

But both didn't work. They are kept being shown as capital letters.

Any idea on how to solve this?

Submitted by support on Thu, 2014-04-03 08:18

Hi Michel,

Have a go with mb_strtolower() (the multi-byte version) instead of strtolower() e.g.

$item["PEGELNAME"] = ucwords(mb_strtolower($item["PEGELNAME"]));

Hope this helps!
Cheers,
David
--
MagicParser.com

Submitted by MvdL1979 on Thu, 2014-04-03 08:25

Hi David,

I used that instead of the other code, so it looks now like this:

$item["PEGELNAME"] = str_replace("-KRONENHOF"," ",$item["PEGELNAME"]);
$item["PEGELNAME"] = str_replace("-OPPENHEIM"," ",$item["PEGELNAME"]);
$item["PEGELNAME"] = str_replace(" STADT"," ",$item["PEGELNAME"]);
//$item["PEGELNAME"] = ucwords(strtolower($item["PEGELNAME"]));
$item["PEGELNAME"] = ucwords(mb_strtolower($item["PEGELNAME"]));

But now the places 'Köln' and 'Düsseldorf' don't show up at all anymore?
It seems they are just removed from it completely...? :S

Regards,
Michel

Submitted by support on Thu, 2014-04-03 08:38

Ah - might be necessary to include the character encoding in that case, e.g.

$item["PEGELNAME"] = ucwords(mb_strtolower($item["PEGELNAME"],"UTF-8"));

Cheers,
David

Submitted by MvdL1979 on Thu, 2014-04-03 08:43

Well this is really getting weird...!

Köln and Düsseldorf are not being shown anymore (like previously), however the next on the list (which I didn't specify) is showing up which is: Giessen Klärwerk (also with 'umlaut').

I think this is caused by my array?
Which uses:

  $include = array("KONSTANZ","....","KÖLN","DÜSSELDORF","....","EMMERICH");

Ignore the dots, I just truncated it for you for easier reading. I am suspecting this is causing now the problem as it's probably changed by the code you gave me and doesn't read it anymore like it should and therefor not saying it's a match and skipping it, right?

Submitted by support on Thu, 2014-04-03 09:39

Hi Michel,

It may be necessary to use the multibyte version of stripos based on the way exlusions and priority records are being implemented - in your code, replace both instances of

stripos

...with:

mb_stripos

Hope this helps! If still no joy, if you could email me your latest versions as there have been a few changes since the last copy I have and I'll check it out further for you...

Cheers,
David

Submitted by MvdL1979 on Thu, 2014-04-03 09:45

Still no "joy" lol...

I will email it to you instead. It seems to completely ignore those two in the array now (as I mentioned above).