1

I'm looking to use the results in an array and sort them using a ranking algorithm similar to say Hacker News or Reddit.

For example, paraphrasing the HN algorithm: Score = P / (T+2)^G

where,
P = points of an item (e.g. votes + comments + likes)
T = time since submission (in hours)
G = Gravity, (on HN defaults to 1.8)

From what I understand, I need to use a PHP sorting array, but the PHP manual is confusing, and the similar answers on StackOverflow have very specific answers without many comments as to what the function is doing. e.g. here, here & here.

My data looks as follows

Array
(
    [0] => Array
        (
            [post_created] => 2011-12-12 07:18:17
            [post_num_likes] => 1
            [post_num_comments] => 0
            [post_message] => Some message
            [votes] => 16
        )

    [1] => Array
        (
            [post_created] => 2011-12-11 22:17:16
            [post_num_likes] => 0
            [post_num_comments] => 4
            [post_message] => Another message
            [votes] => 21
        )

    [2] => Array
        (
            [post_created] => 2011-12-11 20:21:11
            [post_num_likes] => 1
            [post_num_comments] => 2
            [post_message] => Next message
            [votes] => 1
        )

    [3] => Array
        (
            [post_created] => 2011-12-11 20:11:47
            [post_num_likes] => 0
            [post_num_comments] => 0
            [post_message] => Something else
            [votes] => 0
        )

    [4] => Array
        (
            [post_created] => 2011-12-11 20:09:46
            [post_num_likes] => 1
            [post_num_comments] => 0
            [post_message] => Another message 
            [votes] => 5
        )

So far as I understand, I need to do something like the following:

// Send array as 2nd parameter due to way you call functions in CodeIgniter
uksort($array, array('Class_name','postrank'));

function postrank($a, $b) {
    // some sorting function here
    return strcmp($a, $b);
}

I've tried copying and pasting various functions, but as they're not so well commented, it's hard to know what's going on.

How might I go about recreating a similar post ranking sorting function with the above data?

Community
  • 1
  • 1
Joe W
  • 998
  • 6
  • 16
  • 36
  • You need to be more specific about your ranking criterium – abcde123483 Dec 12 '11 at 21:03
  • Hm, how so? It's `(votes + comments + likes) / (created_time + 2) ^G` – Joe W Dec 12 '11 at 21:11
  • so are you wanting us to come up with the algorithm, write it, and write the sorting for you? – Bot Dec 12 '11 at 21:29
  • No, I was hoping I could provide enough information of where my understanding is currently so that someone might suggest how I might go from here. As I mention, there are several similar questions, but the answers are esoteric and presume a level of understanding about PHP sorting arrays in the first place - I have none. Please don't assume the worst about me, I'm lost and hoped if I provide detailed information, links and what I'd already read up on, it might help this novice developer. – Joe W Dec 12 '11 at 21:34
  • There is nothing esoteric about comparing 2 values – abcde123483 Dec 13 '11 at 06:53

3 Answers3

2

amidoinitrite?

SELECT * , (
votes + post_num_comments + post_num_likes - 1
) / POW( ROUND( (
TIME_TO_SEC( TIMEDIFF( NOW( ) , post_created ) ) / 3600 ) + 2 ) , 1.8
) AS score
FROM hacker_news
ORDER BY score DESC

enter image description here

The formula on website is actually: Score = (P-1) / (T+2) ^ G

Dejan Marjanović
  • 19,244
  • 7
  • 52
  • 66
  • This is actually very good. I honestly wasn't aware you do such a thing with an SQL query, so I'm impressed - thank you. – Joe W Dec 12 '11 at 22:12
  • @Joe, everything you can do in SQL, **do it**! :) It is almost in all cases lot faster than sorting/calulating in PHP etc. I'm pretty sure HN does it in SQL. – Dejan Marjanović Dec 12 '11 at 22:13
  • I appreciate it. When you use 'score' as an alias, is that value generated then accessible in the resulting array? – Joe W Dec 12 '11 at 22:26
  • @Joe, yes of course, like `$row['score']`, WYSIWYG on screenshot. – Dejan Marjanović Dec 12 '11 at 22:28
2

My example code for PHP older than 5.3 :)

<?php
function customSort($a, $b){
    foreach(array('a', 'b') as $vn){
        $tmp = $$vn;
        $p = $tmp['post_num_likes'] + $tmp['post_num_comments'] + $tmp['votes'];
        $t = ceil((time() - strtotime($tmp['post_created'])) / 3600);
        $$vn = $p / pow($t + 2, 1.81);
    }
    return $a - $b;
}
usort($array, 'customSort');

var_dump($array);
piotrekkr
  • 2,785
  • 2
  • 21
  • 35
1
$score = function($arr) {
    extract($arr);
    return ($votes + $comments + $likes) / pow($created_time + 2, 1.8);
};

usort($array, function($a, $b) use ($score) {
    return $score($a) - $score($b);
});

This needs php 5.3 because I used anonymous functions.

goat
  • 31,486
  • 7
  • 73
  • 96