Reputation: 1024
I have two 2d arrays as seen below:
$users = [
['username' => 'Timothy'],
['username' => 'Frederic']
];
$users2 = [
['username' => 'Johnathon'],
['username' => 'Frederic'],
['username' => 'Peter']
];
I am trying to compare the contents of each array against each other in order to write html elements. I tried using a nested foreach as seen below:
foreach ($users as $user) {
foreach ($users2 as $user2) {
if ($user['username'] == $user2['username']) {
echo "<option value=' " . $user['username'] . "' selected = 'selected'>" . $user['username'] . "</option>";
break;
} else {
echo "<option value=' " . $user['username'] . "'>" . $user['username'] . "</option>";
}
}
}
My issue is that the items are being echoed more than once which is ruining my select element. Any ideas on how to compare the contents of each without printing duplicated options?
I want to achieve a list of each name eg:
-Timothy
-Frederic (this should be highlighted as it is in both arrays)
-Johnathon
- Peter
Upvotes: 0
Views: 95
Reputation: 47903
Isolate and flatten the column values from both arrays into a single 1d array. Then count the unique values. Then loop over the generated array and print out the desired HTML.
Note that it is never valuable to repeat the text of an option tag as its value
attribute -- it is needless markup bloat. In other words, only declare value
attributes in option tags if the value is different from the visible text of the tag.
Code: (Demo)
$counts = array_count_values(
[
...array_column($users, 'username'),
...array_column($users2, 'username')
]
);
foreach ($counts as $user => $count) {
printf(
"<option%s>%s</option>\n",
$count > 1 ? ' selected' : '',
htmlentities($user)
);
}
Output:
<option>Timothy</option>
<option selected>Frederic</option>
<option>Johnathon</option>
<option>Peter</option>
Upvotes: 0
Reputation: 7948
I would take it in a different way.
//Create user array one
$users = array();
$users[] = array('username'=>'Timothy');
$users[] = array('username'=>'Frederic');
//create user array 2
$users2 = array();
$users2[] = array('username'=>'Johnathon');
$users2[] = array('username'=>'Frederic');
$users2[] = array('username'=>'Peter');
$temp_array = array();
foreach($users as $key => $value) {
$temp_array[$value['username']] = '';
}
foreach($users2 as $key => $value) {
$temp_array[$value['username']] = array_key_exists($value['username'], $temp_array) ? 'DUPLICATE' : null;
}
echo '<select>';
foreach($temp_array as $key_value => $status) {
echo "<option value='{$key_value}' ".(($status == 'DUPLICATE') ? 'selected style="background-color: yellow;"' : '').">{$key_value}</option>";
}
echo '</select>';
I'll let the array take care of it self, if it shares the same key, it will merge, then just flag it with "duplicate".
Upvotes: 1
Reputation: 18898
If there is never any duplicates as you say in each array, the following works for me. This may look a bit complicated, but read through my comments.
You can copy the code and run it in it's own page to see if it works the way you want.
<?php
//Create user array one
$users = array();
$users[] = array('username'=>'Timothy');
$users[] = array('username'=>'Frederic');
//create user array 2
$users2 = array();
$users2[] = array('username'=>'Johnathon');
$users2[] = array('username'=>'Frederic');
$users2[] = array('username'=>'Peter');
//create a new array to combine all of the data, yes, there will be duplicates
$allData = array();
//add to allData array
foreach ($users as $user) {
$allData[] = $user['username'];
}
//add to allData array
foreach ($users2 as $user2) {
$allData[] = $user2['username'];
}
//create an array that will hold all of the duplicates
$dups = array();
//add any duplicates to the array
foreach(array_count_values($allData) as $val => $c) {
if($c > 1) $dups[] = $val;
}
//remove the duplicates from the allData array
$allData = array_unique($allData);
//echo out form
echo '<select>';
foreach ($allData as $user) {
if (in_array($user, $dups)) {
echo "<option value=' ".$user."' selected = 'selected'>".$user."</option>";
}
else {
echo "<option value=' ".$user."'>".$user."</option>";
}
}
echo '</select>';
?>
However, I'm not sure what your intentions are since IF you had "Peter" and "Frederic" in BOTH arrays, you are not going to get the form you want. But, this works for what you wanted.
Upvotes: 1