Merging two arrays removing duplicate keys from one - php

I have two arrays. Those are below:
First Array:
$arr1[0] = 'Programs';
$arr1[1] = 'Levels';
$arr1[2] = 'Presenters';
$arr1[3] = 'Levels';
Second Array:
$arr2[0] = 'Art';
$arr2[1] = 'Primary';
$arr2[2] = 'Kristine Ballard';
$arr2[3] = 'Secondary';
I want to get output like this:
Programs = Art
Levels = Primary, Secondary
Presenters = Kristine Ballard
Can anyone help?

With the following, you would create a multidimensional array, if there are multiple values of a key:
$arr1[0] = 'Programs';
$arr1[1] = 'Levels';
$arr1[2] = 'Presenters';
$arr1[3] = 'Levels';
$arr2[0] = 'Art';
$arr2[1] = 'Primary';
$arr2[2] = 'Kristine Ballard';
$arr2[3] = 'Secondary';
$newArray = array();
foreach($arr1 as $index => $key) {
$newArray[$key][] = $arr2[$index];
}
print_r($newArray);
Output:
Array
(
[Programs] => Array
(
[0] => Art
)
[Levels] => Array
(
[0] => Primary
[1] => Secondary
)
[Presenters] => Array
(
[0] => Kristine Ballard
)
)

$arr1[0] = 'Programs';
$arr1[1] = 'Levels';
$arr1[2] = 'Presenters';
$arr1[3] = 'Levels';
$arr2[0] = 'Art';
$arr2[1] = 'Primary';
$arr2[2] = 'Kristine Ballard';
$arr2[3] = 'Secondary';
$newArray = [];
$mi = new MultipleIterator();
$mi->attachIterator(new ArrayIterator($arr1));
$mi->attachIterator(new ArrayIterator($arr2));
foreach($mi as list($key, $value)) {
$newArray[$key][] = $value;
}
var_dump($newArray);
Note that the use of foreach() with list() requires PHP>=5.5.0
For earlier versions of PHP, the following will work:
$newArray = [];
$mi = new MultipleIterator(MultipleIterator::MIT_NEED_ALL | MultipleIterator::MIT_KEYS_ASSOC);
$mi->attachIterator(new ArrayIterator($arr1), 'key');
$mi->attachIterator(new ArrayIterator($arr2), 'value');
foreach($mi as $details) {
extract($details);
$newArray[$key][] = $value;
}
var_dump($newArray);

I got another solution by myself and this is working. I have just posted it below for the help to others who will see this thread. Here is my code:
$arr1[0] = 'Programs';
$arr1[1] = 'Levels';
$arr1[2] = 'Presenters';
$arr1[3] = 'Levels';
$arr2[0] = 'Art';
$arr2[1] = 'Primary';
$arr2[2] = 'Kristine Ballard';
$arr2[3] = 'Secondary';
$new_arr1 = array_values(array_unique($arr1));
for ($i = 0; $i < count($new_arr1); $i++)
{
$var = 0;
echo $new_arr1[$i]. ': ';
for ($j = 0; $j < count($arr1); $j++)
{
if($new_arr1[$i] == $arr1[$j])
{
if($var == 0)
{
echo $arr2[$j];
}
else
{
echo ', ' . $arr2[$j];
}
$var++;
}
}
echo '<br>';
}

Related

How to group same array values in PHP?

I want to group in subarray the identical values ​​while preserving the original order of each group of values.
I want this :
array('a','b','b','c','c','c','a','a');
to become :
array( array('a'),array('b','b'),array('c','c','c'),array('a','a'));
$source = array('a','b','b','c','c','c','a','a');
$tempvalue = false;
$temparr = array();
$new = array();
foreach ($source as $value) {
if ($tempvalue && $value != $tempvalue){
$new[] = $temparr;
$temparr = array();
}
$temparr[] = $value;
$tempvalue = $value;
}
$new[] = $temparr;
echo json_encode($new);
output:
[["a"],["b","b"],["c","c","c"],["a","a"]]

PHP Two dimensional array

How can I make a two dimensional array with the following example using for loop:
$test = array ('D','D','D','D','C','C','D','D');
output should be like this:
$output = array( 0 => array('D','D','D','D'), 1 => array('D','D'));
thanks for your help.
Here is my code:
$test = array('D','D','D','D', 'C','C','D', 'D');
$output = array();
$myarray = array();
for ($i= 0; $i < count($test); $i++){
if($test[$i] == 'D'){
array_push($myarray , $test[$i]);
} else {
array_push($output,$myarray);
}
}
//OUTPUT: $output = (array( 0 => array('D','D','D','D'), 1 => array('D','D','D','D'));
this can be implemented using only one foreach loop.
<?php
$test = array ('D','C','D','D','D','D','C','C','D','D','C','D');
$temp = array();
$result = array();
foreach($test as $value){
if($value != 'D' && !empty($temp)){
array_push($result, $temp);
$temp = array();
}
else{
array_push($temp, $value);
}
}
if(!empty($temp)){
array_push($result, $temp);
}
print_r($result);

Divide string to assoc array

I have a string like this:
$config = 'app.name = "My App";
app.id = "myappid";
app.components.cache.id = "Memcache";';
I need to convert it to array like this:
app=>[
'name=>'My App',
'id'=>'myappid',
'components'=>[
'cache'=>['id'=>'Memcache']
]
]
I use explode for divide on the pieces, but i don't know what i need to do next.
$arr = explode(";", $config);
$data = [];
foreach ($arr as $item) {
$pieces = explode('=', $item);
$pieces_dotes = explode('.', $pieces[0]);
foreach ($pieces_dotes as $piece) {
//what i need to do here?
}
}
How about this? Within the inner foreach loop, you're assigning the temp variable by reference to itself, so you build a stack of array keys, and then assign the value to it at the end.
$config = 'app.name = "My App";
app.id = "myappid";
app.components.cache.id = "Memcache";';
$arr = explode(";", $config);
$data = [];
foreach ($arr as $item) {
$temp = &$data;
$item = trim($item);
if (empty($item)) continue;
list($setting, $value) = explode("=", trim($item));
$setting = explode(".", trim($setting));
foreach ($setting as $set) {
$temp = &$temp[$set];
}
$temp = trim($value, '" ');
}
print_r($data);
This can be solved by building the array levels based on the key and keeping a reference to the last added level in the array. My solution (based on what you already had) is as follows:
<?php
$config = 'app.name = "My App";
app.id = "myappid";
app.components.cache.id = "Memcache";';
$arr = explode(";", $config);
$data = [];
foreach ($arr as $item) {
$pieces = explode('=', $item);
$currentValue = trim(str_replace('"', '', $pieces[1]));
$pieces_dotes = explode('.', $pieces[0]);
// Set initial value of $currentLevel to root of data array
$currentLevel = &$data;
// Initiate count & iterator vars
$numPieces = count($pieces_dotes);
$i = 0;
foreach ($pieces_dotes as $piece) {
// Increment $i and set $newKey to be trimmed version of current piece of the dot notated level
$i++;
$newKey = trim($piece);
// Skip empty $newKey
if(empty($newKey)) {
continue;
}
// Assign the $currentValue once we are at the required depth
if($i == $numPieces) {
$currentLevel[$newKey] = $currentValue;
}
// We are not at the required depth yet so initiate the key as an array if required
if(empty($currentLevel[$newKey])) {
$currentLevel[$newKey] = [];
}
// Set the $currentLevel to reference the new key
if(is_array($currentLevel[$newKey])) {
$currentLevel = &$currentLevel[$newKey];
}
}
}
Hope this helps!
The solution using custom recursive function fillBypath:
/**
* Fills an array by hierarchical 'key path'
*
* #param type $value value in each 'key path'
* #param type $keys hierarchical key list
* #param type $arr the resulting array(passed by reference)
*/
function fillByPath($value, $keys, &$arr) {
$c = count($keys) - 1;
foreach ($keys as $idx => $k) {
if ($idx == $c) { // check if it's the last key in the "key path"
$arr[$k] = $value;
break;
}
if (isset($arr[$k]) && is_array($arr[$k])) {
fillByPath($value, array_slice($keys, $idx + 1), $arr[$k]);
break;
} else {
$arr[$k] = [];
fillByPath($value, array_slice($keys, $idx + 1), $arr[$k]);
break;
}
}
}
$config = 'app.name = "My App";
app.id = "myappid";
app.components.cache.id = "Memcache";';
$result = [];
foreach (array_filter(explode(";", $config)) as $path) {
list($keyPath, $v) = explode(" = ", trim($path));
$keys = explode(".", $keyPath); // getting key list
fillByPath($v, $keys, $result);
}
print_r($result);
The output:
(
[app] => Array
(
[name] => "My App"
[id] => "myappid"
[components] => Array
(
[cache] => Array
(
[id] => "Memcache"
)
)
)
)

PHP: Sort multidimensional array, but keep its substructure

I have a multidimensional arrays with the following structure:
$arr[0][0] = 1.24;
$arr[0][1] = 5.21;
$arr[0][2] = 2.72;
$arr[0][3] = 1.89;
$arr[0][4] = 4.62;
$arr[1][0] = 3.45;
$arr[1][1] = 5.61;
$arr[1][2] = 2.62;
$arr[1][3] = 1.12;
$arr[1][4] = 1.35;
This array should get sorted while keeping the suborder of $arr[0] and $arr[1], so the result looks like this:
$arr[0][0] = 1.24;
$arr[1][0] = 3.45;
$arr[0][1] = 5.21;
$arr[0][2] = 2.72;
$arr[0][3] = 1.89;
$arr[0][4] = 4.62;
$arr[1][2] = 2.62;
$arr[1][3] = 1.12;
$arr[1][4] = 1.35;
$arr[1][1] = 5.61;
I do not care in which form the result get saved, but I need both keys and the value. Hope you understand and can help me.
How about looping the outer array and sorting the inner?
foreach ($arr as $id => $data) {
sort($data);
$arr[$id] = $data;
}
$arr[0][0] = 1.24;
$arr[0][1] = 5.21;
$arr[0][2] = 2.72;
$arr[0][3] = 1.89;
$arr[0][4] = 4.62;
$arr[1][0] = 3.45;
$arr[1][1] = 5.61;
$arr[1][2] = 2.62;
$arr[1][3] = 1.12;
$arr[1][4] = 1.35;
$size = count($arr);
$outArr= array();
foreach($arr[0] as $key =>$value)
{
$resArr = array();
for($i = 0 ; $i< $size ; $i++)
{
$resArr[] = $arr[$i][$key] ;
}
sort($resArr);
$outArr[$key] = $resArr;
}
echo "<pre>";
print_r($outArr);
Check if this is a closer solution.

PHP array comparison and finding matched and non matched items

I have been using this script for finding matched and nonmatched array items.
My code is.
$filter1 = "red,green,blue,yellow";
$parts1 = explode(',', $filter1);
$filter2 = "red,green,blue";
$parts2 = explode(',', $filter2);
for($i=0; $i< count($parts1); $i++)
{
for($j=0; $j< count($parts2); $j++)
{
if($parts1[$i] == $parts2[$j])
{
$match[] = $parts1[$i];
} else {
$nomatch[] = $parts1[$i];
}
}
}
print_r($match);
echo "<br>";
print_r($nomatch);
By using this code i am only getting the matched items and not nonmatched. Can anybody help.
Thanks in advance.
You can try using array_intersect and array_diff
$filter1 = "red,green,blue,yellow";
$parts1 = explode(',', $filter1);
$filter2 = "red,green,blue";
$parts2 = explode(',', $filter2);
$match = array_intersect($parts1, $parts2);
$nomatch = array_diff($parts1, $parts2);
var_dump($match,$nomatch);
Output
array
0 => string 'red' (length=3)
1 => string 'green' (length=5)
2 => string 'blue' (length=4)
array
3 => string 'yellow' (length=6)
this can be done by array_intersect and array_diff
$filter1 = "red,green,blue,yellow";
$parts1 = explode(',', $filter1);
$filter2 = "red,green,blue";
$parts2 = explode(',', $filter2);
$result = array_intersect($parts1 , $parts2 );
print_r($result);
Live Example
and
$result = array_diff($parts1 , $parts2 );
print_r($result);
LIVE example
because your nested loop not run at yellow color time
try this
$filter1 = "red,green,blue,yellow";
$filter2 = "red,green,blue,gray";
or
for($j=0; $j<= count($parts2); $j++)
$filter1 = "red,green,blue,yellow";
$parts1 = explode(',', $filter1);
$filter2 = "red,green,blue";
$parts2 = explode(',', $filter2);
$match = array();
$nomatch = array();
foreach($parts1 as $v){
if(in_array($v,$parts2))
$match[]=$v;
else
$nomatch[]=$v;
}
try this
$filter1 = "red,green,blue,yellow";
$parts1 = explode(',', $filter1);
$filter2 = "red,green,blue";
$parts2 = explode(',', $filter2);
foreach($parts1 as $first)
{
if(in_array($first, $parts2))
{
$match[] = $first;
}
else
{
$nomatch[] = $first;
}
}
print_r($match);
echo "<br>";
print_r($nomatch);
or you can use array_diff to get non matched items
print_r(array_diff($parts1,$parts2));
and for matched items use
print_r(array_intersect($parts1,$parts2));
Try the below code
$filter1 = "red,green,blue,yellow";
$parts1 = explode(',', $filter1);
$filter2 = "red,green,blue,purple";
$parts2 = explode(',', $filter2);
$matching = array_intersect($parts1, $parts2);
$non_matching = array_diff(array_merge($parts1, $parts2), $matching);
Changing your code, which should have similar result for non-matching as array_diff($parts1, $parts2);
for($i=0; $i< count($parts1); $i++)
{
$is_matching = false;
for($j=0; $j< count($parts2); $j++)
{
if($parts1[$i] == $parts2[$j])
{
$is_matching = true;
break;
}
}
if ($is_matching) {
$match[] = $parts1[$i];
} else {
$nomatch[] = $parts1[$i];
}
}
You can find matching value using array_intersect and non matching value using array_diff.
Here you can see LIVE DEMO
/**
* #param $arr
*/
function pr($arr)
{
echo '<pre>';
print_r($arr);
echo '</pre>';
}
$filter1 = "red,green,blue,yellow";
$parts1 = explode(',', $filter1);
$filter2 = "red,green,blue";
$parts2 = explode(',', $filter2);
$match = array_intersect($parts1, $parts2);
$nomatch = array_diff($parts1, $parts2);
pr($match);
pr($nomatch);
Output Screen:
Array
(
[0] => red
[1] => green
[2] => blue
)
Array
(
[3] => yellow
)

Categories