Search code examples
phpmultidimensional-arrayunique-id

generate unique id for array value groups


I have an asosiative array which contains data about teams and players.

Example:

$arr = array(
  array('teamID'=> '','teamName' => 'USA', 'playerName'='John'),
  array('teamID'=> '','teamName' => 'USA', 'playerName'='Peter'),
  array('teamID'=> '12','teamName' => 'Norway', 'playerName'='Zigmund'),
  array('teamID'=> '','teamName' => 'USA', 'playerName'='Parker'),
  array('teamID'=> '','teamName' => 'Norway', 'playerName'='Jan'),
  array('teamID'=> '','teamName' => 'USA', 'playerName'='Hector'),
  array('teamID'=> '','teamName' => 'Germany', 'playerName'='Alexander'),
  array('teamID'=> '','teamName' => 'Slovakia', 'playerName'='Ivan')
);

I want to generate unique ID for each team if it is not present, if the id is present for some team use it on same team names if they dont exist there, and do not use id's which already exists.

What I have did is simple check if not exists ad index of the foreach loop, bet then it is per player not per team.

Expected outcome:

$arr = array(
  array('teamID'=> '1','teamName' => 'USA', 'playerName='John'),
  array('teamID'=> '1','teamName' => 'USA', 'playerName'='Peter'),
  array('teamID'=> '12','teamName' => 'Norway', 'playerName'='Zigmund'),
  array('teamID'=> '1','teamName' => 'USA', 'playerName'='Parker'),
  array('teamID'=> '12','teamName' => 'Norway', 'playerName'='Jan'),
  array('teamID'=> '1','teamName' => 'USA', 'playerName'='Hector'),
  array('teamID'=> '2','teamName' => 'Germany', 'playerName'='Alexander'),
  array('teamID'=> '3','teamName' => 'Slovakia', 'playerName'='Ivan')    
);

Any ideas on how to solve this?


Solution

  • This would solve your problem (as one of many possible solutions). Here we have an array holding each team name as a key, and an incremented numerical ID for every occurence of a new team name. Then we check if the key exists, if it does, we reuse the ID that is assigned to it. If it doesn't exist, we create it and add an ID, and then increment the integer.

    $teams_with_ids = [];
    $teamids = [];
    $i=0;
    foreach( $arr AS $team ){
        if( array_key_exists($team['teamName'], $teamids) ){
            $team['teamID'] = $teamids[$team['teamName']];
        } else {
            $teamids[$team['teamName']] = $i;
            $team['teamID'] = $i;
            $i++;
        }
        array_push($teams_with_ids, $team);
    }
    

    EDIT:

    As pointed out in the comment, the above solution did not account for existing ID's on some teams. This does:

    $teams_with_ids = [];
    $teamids = [];
    $existing_ids = array_filter((array_map(function($team){ if( !empty( $team['teamID'] ) ) return intval($team['teamID']); },$arr)));
    $i=0;
    foreach( $arr AS $team ){   
        if( array_key_exists($team['teamName'], $teamids) ){
            $team['teamID'] = $teamids[$team['teamName']];
        } else {
            if( in_array( $i, $existing_ids ) ) $i++; // Adding +1 to $i since the ID is already taken
            $teamids[$team['teamName']] = (!empty($team['teamID']) && in_array($team['teamID'], $existing_ids)) ? $team['teamID'] : $i;
            $team['teamID'] = (empty($team['teamID'])) ? $i : $team['teamID'];
            if( empty($team['teamID'] ) ) $i++;
        }
        array_push($teams_with_ids, $team);
    }