I am using the get_posts
provided by WordPress to supply an array of post objects. A simplified version of this array is the following;
$zones = array
0 =>
object
public 'post_title' => string 'Zone Five: Banana'
1 =>
object
public 'post_title' => string 'Zone Eight: Banana'
2 =>
object
public 'post_title' => string 'Zone Six: Banana'
3 =>
object
public 'post_title' => string 'Zone Seven: Banana'
4 =>
object
public 'post_title' => string 'Zone Four: Cherry'
5 =>
object
public 'post_title' => string 'Zone Two: Orange'
6 =>
object
public 'post_title' => string 'Zone Three: Avocado'
7 =>
object
public 'post_title' => string 'Zone One: Apple'
As you can see, the post titles are not in order. Obviously an alphabetical sort won’t work.
Ideally, the first item of the array would be Zone One: Apple
, and the last one being Zone Eight: Banana
I figured that usort
would be the PHP function to use, but I can’t figure out how to compare substrings as opposed to an entire string.
Here is some code that works for Full text matching; (borrowed from another helpful stack overflow post)
$order = array_flip(['Zone One: Apple', 'Zone Two: Orange', 'Zone Three: Avocado', 'Zone Four: Cherry', 'Zone Five: Banana', 'Zone Six: Banana', 'Zone Seven: Banana', 'Zone Eight: Banana']); // restructure with values as keys, and keys as order (ASC)
$outlier = 1 + max($order);
usort($zones, function ($a, $b) use (&$order, $outlier) { // make $order modifiable with &
if (!isset($order[$a->post_title])) {$order[$a->post_title] = $outlier;} // update lookup array with [id]=>[outlier number]
if (!isset($order[$b->post_title])) {$order[$b->post_title] = $outlier;} // and again
return $order[$a->post_title] <=> $order[$b->post_title];
});
Ideally, I’d like to sort by substring;
$order = [‘One’, ‘Two’, ‘Three’, ‘Four’, ‘Five’, ‘Six’, ‘Seven’, ‘Eight’];
2
Answers
Take note that the code below meant to give you an example of what you can do. This code below will only work up to Ten. If you have eleven or nothing its behaviour could be undefined.
For your issue, you need to parse number as words to actual int value and compare them. Thus, you need to somehow get the number as words out of the string. Thus, you need a dictionary of number as words to int values.
It could be hard if you run a code that utilizes regexes the strings for every possible word that is a number. The other solution is if your title always starts with “zone” and then “number” then the “:”. You can split or substr or whichever method you feel efficient. That is the hard part. But after that, it is a breeze.
One you found that number word, you convert it to int values and compare them and use the value appropriately.
One thing to take into consideration is that what happens if one of the strings in the array does not contain a number?
This does make assumptions that all of the data is structured how you say it is, as there isn’t any checks to ensure the data is of the right format. It also relies on PHP 7+ for small thinks like the spaceship operator (
<=>
) in the comparison…