The code below puts data into an array, sorts it then displays as a list of articles/data. The problem is that the result lists a selection of different articles from different categories, what I need is to only show the articles that match a certain column. The column I need to match is ext_column_1.
I was thinking something like $cat = isset($activePage->ext_column_1), though I’m not sure how to add another function or what to do here.
My question, how do I only show the page items that match the ext_column_1 column?
Are you pulling it from the database? If so you can add a where clause, if not use a loop and and an inner if statement and build a new array filled with the desired data.
After chatting with a colleague who helped me, array_filter is what we needed, as @StarLion also mentioned, and thanks @animedreamz73. First time I’ve used array_filter. Not sure exactly how this code is working, though have a good idea whats happening, everything works
Full solution:
function cat($element){
global $cat;
return($element['cat']==$cat);
}
$cat = $activePage->ext_column_1;
Then further down where I loop through the results:
Impressive! Thanks @StarLion, I’ll make note.
Might try to modify this if this would improve things. Everything works, don’t want to mess with things just yet
I would have filtered before the foreach.
What is the benefit?
And one thing I keep seeing, and you’ve just used it yourself is unset()
Lets say topPage->getChildren gets… 100 records. These are now an array, which you put into $articlePages.
Next, you foreach that array; So that’lll be 100 loops through the code.
Now you store all the relevant information about EVERY article into your $overAllArray2Sort array. So it’s got 100 entries in it at the end, and looks an awful lot like your original array. At this point, you’re using up basically double the memory to hold the same piece of information. Oh and you also ran strtotime function on all 100 dates.
Then you array filter. Now you throw away everything that doesnt match your filter - in this case, that the category matches. So now your overallArray2Sort contains… lets say 20 items.
However, if you filter FIRST, you can wheedle this down a lot easier.
Now when you ‘create’ your first array, it’s got 20 items in it.
At this point, you… dont really need to do anything with date, because you never use it in this script. For that matter, you dont seem to need the second array at all, given what you’ve shown us – there’s certainly a lot more optimizing of code that can be done here! But even if you wanted to create the second array for other things you do, now you only have to do 20 loops to cover all of the data - only 20 calls to strtotime, 20 array entry creations, etc - saving script execution time, and memory usage.
Narrowing down the data to the relevant data before doing work on it will save in the long run.
Thank you! One of the best explanation I’ve had for some time, really helps.
After reading this, I see exactly what you’re saying now, and does make perfect sense. Previously I was working with this code before introducing the $overAllArray2Sort array, this was needed because of the cms and not being able to sort these columns from the database. Though won’t go into that, had a major thread some time back.
The reason I’m using the date is because I’m displaying articles and sorting them by date, also displaying the date as show below, this is what sits underneath. Are you saying I don’t need that now?
Get the page data for the 9th remaining article. (Because you overwrite $articlePage every time through the loop).
Let me take a swing at it instead, and see if this makes sense to you:
<?php
$articlePages = array_filter(topPage->getChildren(null,true),"only_this_cat");
usort($articlePages,"by_date"); //Now my data is trimmed down, and in order.
$articlePage = $pageNav->getPage($articlePages[8]->page_id);
function only_this_cat($element) {
global $activePage;
return $activePage->ext_column_1 == $element->ext_column_1;
}
function rcmp($a, $b)
{
if ($a->ext_column_4 == $b->ext_column_4) { //Really, a timestamp SHOULD be being used here. BUT. Y-M-D will allow sorting.
return 0;
}
return ($a->ext_column_4 < $b->ext_column_4) ? 1 : -1;
}
?>
I’ll need to digest this and have a crack in a more testing environment, this code is part of a site I’ve been working on for the past 2 months, suppose to go live next week ha.
For the record, each article/page is a sub/child from the parent page/category (which displays articles only for that section), and there are numerous categories. This section we’re working on, is only allowed to show related articles from that category in the footer. Likewise with the other categories where this code also runs, hence “only_this_cat”. This will put the sub-array elements into more perspective for you.
I didn’t realise.
Again, thanks for all your help with this StarLion, either way, if I use this update or not, learnt a lot here and will use these techniques for future projects and maybe updates to this project, possible localisations.
In short, I see right away you’re concentrating on performance, a good way to approach things, speed amongst other things. As things are, it’s unlikely I’ll go past 1000 articles over a 12 month period. But still adds up all those loops
Generalize your compare method. You might want to reuse it again but it is looking for specific data. Also your reserving way to much memory for the data, 255 characters for a 10 character string.
Lastly your cat function could use the variable as a reference and change it’s value.
function cat( &$element )
{
global $cat;
$element[‘cat’] = $cat;
}
Unless your trying to do a boolean comparison then just use an if statement to reduce your method call count and improve speed and memory.
the cat method (and the similar only_this_cat) is a boolean-returning function that does not modify the value of the element. It must be a boolean returning function to work with array_filter.
You could technically generalize the comparison function down more, but it would then require a further variable.