tags:

views:

177

answers:

2

Hi,

I am creating a custom social network for one of my clients.

In this I am storing the friends of a user in the form of CSV as shown below in the user table

uid    user_name      friends
1      John           2
2      Jack           3,1
3      Gary           2,4
4      Joey           3

In the above scenario if the logged in user is John and if he visits the profile page of Joey, the connection between them should appear as

John->Jack->Gary->Joey

I am able to establish the connection at level 1 i.e

If Jack visits Joey's profile I am able to establish the following :

Jack->Gary->Joey

But for the 2nd level I need to get into the same routine of for loops which I know is not the right solution + I am not able to implement that as well.

So, can someone please help me with this?

Thanks in Advance,
Akash

P:S I am not in a position to change the db architecture :(

A: 

Here's some bfs code I had written in ruby; it should give you a good enough idea of how things work to translate it to php. the other change you'll need to make is to replace graph[current] with a db query to get the current user's friends.

def bfs(graph, start, stop)
  queue = [start]
  visited = {}
  parents = {}
  current = nil
  while true
    if queue.empty?
      return nil
    end
    current = queue.shift
    if current == stop
      return read_path(current, parents)
    end
    visited[current] = true
    graph[current].each do |i|
      if not visited[i] and not queue.index(i)
        parents[i] = current
        queue.push(i)
      end
    end
  end
end

def read_path(node, parents)
  a = [node]
  while parents[node]
    a.push(parents[node])
    node = parents[node]
  end
  return a.reverse
end

GRAPH = {
  "a" => ["b", "c"], 
  "b" => ["c", "d"],
  "c" => ["a", "e"],
  "d" => ["b", "c", "f"],
  "e" => ["c", "f"]
}

path = bfs(GRAPH, "a", "f")
p path
Martin DeMello
A: 

Here's some sample code:

<?php

$currentUID = 1; // The logged in user
$pageUID = 4; // The user whose page is being visited

// Parse the CSV
$csv = explode("\n", $csvData);
$csvlen = count($csv);
for($i=0;$i<$csvlen;$i++) {
    $csv[$i] = explode(",", $csv[$i]);
}

function getFriends($csv, $uid) {
    foreach($csv as $user)
     if($user[0] == $uid)
      return explode(',', $user[2]);
}

$userFriends = getFriends($csv, $currentUID);
$pageFriends = getFriends($csv, $pageUID);

$friendPool = array();
foreach($userFriends as $friend) {
    $hisFriends = getFriends($friend);
    foreach($hisFriends as $subFriend) {
     if(in_array($subFriend, $pageFriends)) {
      if(isset($friendPool[$friend]))
       $friendPool[$friend][] = $subFriend;
      else
       $friendPool[$friend] = array( $subFriend );
     }
    }
}

foreach($friendPool as $friend=>$subFriends)
    foreach($subFriends as $subFriend)
     echo "$currentUID -> $friend -> $subFriend -> $pageUID\n";
mattbasta
And let me just add that although it's "necessary", using a CSV for your app is a VERY BAD IDEA. The algo that I have here will only take exponentially longer to run as the number of users increases (n^3). Using a real RDBMS will significantly improve the performance of your application.
mattbasta