chunterb
chunterb

Reputation: 351

PHP Comparing Key/Value in Multidimensional Array Made from CSV

I have two(2) .csv files as such:

CompanySubset.csv

| id | company   | description               |
|----|-----------|---------------------------|
| 1  | Apple     | Description for Apple     |
| 2  | Microsoft | Description for Microsoft |
| 3  | IBM       | Description for IBM       |


ContactSubset.csv

| id | name  | address           | phone       |
|----|-------|-------------------|-------------|
| 1  | Bob   | 1234 Address Lane | 1+234567890 |
| 2  | Sally | 4321 Address Lane | 1+987654321 |
| 3  | Cam   | 2468 Address Lane | 1+468135901 |

Using php, I need to read each file and compare the id column for matches between the two(2). If I find a matching id between the two(2), then I need to merge that specific row together.

Ex: CompanySubset id 1 matches ContactSubset id 1. Therefore, the row with an id of 1 on ContactSubset will be merged with row 1 on CompanySubset. Which will then form the following:

| id | company | description           | name | address           | phone       |
|----|---------|-----------------------|------|-------------------|-------------|
| 1  | Apple   | Description for Apple | Bob  | 1234 Address Lane | 1+234567890 |

I have been able to get each .csv into an array(see below), but thats about it.

$filename = 'CompanySubset.csv';

$company_array = [];

if (($handle = fopen("{$filename}", "r")) !== FALSE) {

    while (($companyData = fgetcsv($handle, 1000, ",")) !== FALSE) {
        $company_array[] = $companyData;
    }

    fclose($handle);
}

Upvotes: 0

Views: 134

Answers (4)

Nigel Ren
Nigel Ren

Reputation: 57121

This solves it by first reading the ContactSubset.csv and creating an array indexed by the first field (removing it from the result using array_shift()).

Then the second loop is virtually the same as your code already, but as it reads each line it checks for the contact details and uses array_merge() to add in the extra details...

$filename = 'ContactSubset.csv';
$contact_array = [];

if (($handle = fopen($filename, "r")) !== FALSE) {
    while (($contactData = fgetcsv($handle)) !== FALSE) {
        $id = array_shift($contactData);
        $contact_array[$id] = $contactData;
    }
    fclose($handle);
}

$filename = 'CompanySubset.csv';
$company_array = [];

if (($handle = fopen($filename, "r")) !== FALSE) {
    while (($companyData = fgetcsv($handle)) !== FALSE) {
        if ( isset($contact_array[$companyData[0]]) )   {
            $companyData = array_merge($companyData, $contact_array[$companyData[0]]);
        }
        $company_array[] = $companyData;
    }

    fclose($handle);
}
print_r($company_array);

Upvotes: 0

Barmar
Barmar

Reputation: 781096

You need to use the id element as the keys of the arrays. Then you can merge the related rows.

$filename = 'CompanySubset.csv';

$company_array = [];

if ($handle = fopen($filename, "r")) {
    while ($companyData = fgetcsv($handle, 1000, ",")) {
        $company_array[$companyData[0]] = array_slice($companyData, 1);
    }
    fclose($handle);
}

$filename = 'ContactSubset.csv';

$contact_array = [];

if ($handle = fopen($filename, "r")) {
    while ($contactData = fgetcsv($handle, 1000, ",")) {
        $contact_array[$companyData[0]] = array_slice($contactData, 1);
    }
    fclose($handle);
}

See Merging two PHP arrays with same numeric key for methods to merge the array elements with the same keys.

There's also no need for all those !== FALSE tests, just use the value of the assignment as the conditional expression (there are a few times when this is needed, e.g. testing the result of array_search() because 0 is falsey, but none of your uses require it).

Upvotes: 1

Valentin Knyazev
Valentin Knyazev

Reputation: 166

  1. Create two two-dimensional arrays with id's as a keys out of your csv's.
  2. Use https://www.php.net/manual/ru/function.array-intersect-key.php to get set of id's that intersect between two.
  3. Iterate through set of id's from step 2 if there is any and compare actual values.

Upvotes: 0

Rakesh Jakhar
Rakesh Jakhar

Reputation: 6388

Following function has been used:

array_walk() - Apply a user supplied function to every member of an array

array_merge - Merge one or more arrays

Solution:

$companySubset = [
  1 => ['Apple','Description for Apple'],
  2 => ['Microsoft','Description for Microsoft'],
  3 => ['IBM','Description for IBM']
];

$contactSubset = [
 1 => ['Bob','1234 Address Lane','1+234567890 '],
 2 => ['Sally','4321 Address Lane','1+987654321'],
 3 => ['Cam','2468 Address Lane','1+468135901']
];
$res =[];
array_walk($companySubset, function($v,$k) use ($contactSubset, &$res){
  $res[] = array_key_exists($k, $contactSubset) ? array_merge($v,$contactSubset[$k]) : $v;
});

Upvotes: 0

Related Questions