Multidimensional associative unique - php

I have 2x multidimensional array's as show below:
$x = [
0=>[
'a',
'b'
],
1=>[
'c',
'd'
],
2=>[
'e',
'f'
]
];
$y = [
0=>[
'b',
'a'
],
1=>[
'g',
'h'
],
2=>[
'i',
'j'
]
];
I would like to merge the 2x array's (x and y) with an output like this
$xy = [
0=>[
'c',
'd'
],
1=>[
'e',
'f'
],
2=>[
'g',
'h'
],
3=>[
'i',
'j'
]
];
As you can see, $x[0] is equal to a,b and $y[0] equal to b,a and they are duplicated. I would like to know if it's possible for a,b as same as b,a , I don't know how to get my code to look like this. I want to eliminate my duplicated array (a,b != b,a). Any duplication are not allowed, is that possible?

This should give you exactly what you've requested. I've used multiple foreach() loops to test if the value is firstly part of the $Y array, if so then remove from both arrays using unset(). I've then merged the two arrays together, removed the empty array dimensions and reset the key count.
$x = [0=>['a','b'],1=>['c','d'],2=>['e','f']];
$y = [ 0=>['b','a'],1=>['g','h'],2=>['i','j']];
foreach ($x as $key=>$value) {
foreach($x[$key] as $k=>$v) {
$search = array_search($v, $y[$key], true); //Find if value is equal to value in Y using a search
if ($search !== false) { //If so then remove value
unset($y[$key][$search]); //Remove from Array Y
unset($x[$key][$search]); //Remove from Array X
}
}
}
$newArray = array_merge($x, $y); //Merge two arrays together
foreach($newArray as $key => $value) { //Remove empty dimensions from Array
if (count($newArray[$key]) <= 0) {
unset($newArray[$key]);
}
}
$newArray = array_values($newArray); //Re-Number Keys so there in order
var_dump($newArray); //Array Output
Output
{
[0] => array(2) {
[0] => string(1)
"c" [1] => string(1)
"d"
}[1] => array(2) {
[0] => string(1)
"e" [1] => string(1)
"f"
}[2] => array(2) {
[0] => string(1)
"g" [1] => string(1)
"h"
}[3] => array(2) {
[0] => string(1)
"i" [1] => string(1)
"j"
}
}
Edit
Added unset() to remove value from both arrays as it's mentions that you would NOT like to have duplicate data from either array shown in new array.

Related

PHP - Get the keys of values which are congruent in an array

I have an array which potentially is able to carry multiple congruent values.
$a = array( "0" => "red", "1" => "green" , "2" => "red" , "3" => "blue", "4" => "blue", "5" => "blue" );
Now, I need to know the keys of all elements which have at least one congruent value.
My prefered result would be an array which has subarrays- and in each subarray the keys of the different congruent values get stored. So that I know which one of the keys of array $a have the same value.
$b = array(array("0" => "0", "1" => "2"), array("0" => "3", "1" => "4", "2" => "5"));
What is the most efficient way to do that?
Thank you
You can use array_count_values() to get the frequency count for each color. Then iterate over the array $a and check each color's frequency count. If it's greater than 1, add it to the result at the appropriate color index in $keys.
<?php
$a = array( "0" => "red", "1" => "green" , "2" => "red" , "3" => "blue", "4" => "blue", "5" => "blue" );
$group_by_data = array_count_values($a);
$keys = [];
foreach($a as $key => $color){
if($group_by_data[$color] > 1){
if(!isset($keys[$color])) $keys[$color] = [];
$keys[$color][] = $key;
}
}
print_r($keys);
Demo: https://3v4l.org/mI02u
Use array_unique to find all unique values then loop through it and use array_keys to find all the keys of each element.
$a = array( "0" => "red", "1" => "green" , "2" => "red" , "3" => "blue", "4" => "blue", "5" => "blue" );
$unique=array_unique($a);
$result=array();
foreach($unique as $value){
$allkeys=array_keys($a, $value);
if(count($allkeys)>1)
$result[]=$allkeys;
}
print_r($result);
Just to have a play with performance, I tried using a (sort of) combination of the two approaches. First count the values, then loop over this and use array_keys() to get the entries with these colors...
$a = array( "0" => "red", "1" => "green" , "2" => "red" , "3" => "blue", "4" => "blue", "5" => "blue" );
$group_by_data = array_count_values($a);
$keys = [];
foreach ( $group_by_data as $key => $value ) {
if ( $value > 1 ) {
$keys[$key] = array_keys($a, $key);
}
}
print_r($keys);

Padding data for sometimes missing object index

I have an array where I'm looping on an object
foreach ($product->info->details as $details) {
$skuItem[] = $details->dtl1;
$skuItem[] = $details->dtl2;
$skuItem[] = $details->dtl3;
}
The object it loops on is structured this way
"details": {
"1": {
"dtl1": "123",
"dtl2": "TEst",
"dtl3": "123"
},
"2": {
"dtl1": "12",
"dtl2": "Test",
"dtl3": "153"
}
},
The thing is, it can only have up to 2 of those sets but sometimes it has only one.
Is there a way to accomodate in my foreach loop so that if there is only one then I can basically 'dummy up' a second set with all zeroes? I'm mapping this to a file and need to make sure I'm at least always mapping all 6 values
So if the object looks like
"details": {
"1": {
"dtl1": "123",
"dtl2": "TEst",
"dtl3": "123"
}
I would want to create my array like
0 => "123",
1 => "TEst",
2 => "123"
3 => "0",
4 => "0",
5 => "0"
After the foreach, you can pad your array with zero:
foreach ($product->info->details as $details) {
$skuItem[] = $details->dtl1;
$skuItem[] = $details->dtl2;
$skuItem[] = $details->dtl3;
}
Array now contains:
0 => "123"
1 => "TEst"
2 => "123"
Now run:
$skuItem = array_pad($skuItem, 6, 0);
This will add zeros to the end of the array until you get 6 items in it, so the array now contains:
0 => '123'
1 => 'TEst'
2 => '123'
3 => 0
4 => 0
5 => 0
If you want string zero instead, then just pass that as the 3rd arg:
$skuItem = array_pad($skuItem, 6, '0');
Yields:
0 => '123'
1 => 'TEst'
2 => '123'
3 => '0'
4 => '0'
5 => '0'
You can create a template of what you want and replace with what you create in the loop:
$skuItem = array_replace(array_fill(0, 6, 0), $skuItem);
array_pad is probably better for this trivial example, but consider if you have a variety of values:
$temp = array('x', 'y', 'z', 'x', 'y', 'z');
$skuItem = array_replace($temp, $skuItem);
Or:
$temp = array('x', 'y', 'z');
if(count($skuItem) != 6) {
$skuItem = array_merge($skuItem, $temp);
}

Codeigniter - merge multiple associative array with condition

I need to merge multiple arrays into one where a specific key & its value are same. Here is the Sample_Array1
array(n) {
[0]=> array {
["a"]=> "m1"
["b"]=> "x2"
}
[1]=> array {
["a"]=> "n1"
["b"]=> "y2"
} ....
Sample_Array2 with one common key & other different ones.
array(n) {
[0]=> array {
["b"]=> "x2"
["c"]=> "p1"
}
[1]=> array {
["b"]=> "x2"
["d"]=> "q1"
}
[2]=> array {
["b"]=> "y2"
["e"]=> "r1"
} ....
Need to merge / append Sample_Array2 to Sample_Array1 where key-"b" & its value are same. The expected output:
array(n) {
[0]=>
array(2) {
["a"]=> "m1"
["b"]=> "x2"
["c"]=> "p1"
["d"]=> "q1"
}
[1]=>
array(2) {
["a"]=> "n1"
["b"]=> "y2"
["e"]=> "r1"
} ....
I have tried so many similar questions but couldn't find the exact result.
PHP merge arrays with a condition The answer given on this link is not solving the purpose, its making different array for each new key, while I need to append the new keys in one array.
This should work, assuming you have the "b" index in all sub arrays.
$array1 = array();
$array1[] = array("a" => "m1", "b" => "x2", "c" => null);
$array1[] = array("a" => "n1", "b" => "y2");
$array2 = array();
$array2[] = array("b" => "x2", "c" => "p1");
$array2[] = array("a" => null, "b" => "x2", "d" => "q1");
$array2[] = array("b" => "y2", "e" => "r1");
function merge_on_key($array1, $array2, $key) {
$result_array = array();
foreach($array1 as $key1 => $sub_array1) {
$merged_array = array();
$sub_array1 = array_filter($sub_array1);
foreach($array2 as $key2 => $sub_array2) {
$sub_array2 = array_filter($sub_array2);
if($sub_array1[$key] == $sub_array2[$key]) {
$merged_array = array_merge($sub_array1, $sub_array2, $merged_array);
unset($array2[$key2]);
}
}
if (!empty($merged_array)) {
$result_array[] = $merged_array;
}
}
return array_merge($result_array, $array2);
}
$final_array = merge_on_key($array1, $array2, "b");
print_r($final_array);
In case you have to match the "b" index within the $array1 itself too, then simply use it twice:
$array1 = merge_on_key($array1, $array1, "b");
$final_array = merge_on_key($array1, $array2, "b");
i really have no idea what you want to achieve here - but based on your description the following code works
$arrA = [
0 =>
[
'a' => 'm1',
'b' => 'x2'
],
1 =>
[
'a' => 'n1',
'b' => 'y2'
]
];
$arrB = [
0 =>
[
'b' => 'x2',
'c' => 'p1',
],
1 =>
[
'b' => 'x2',
'd' => 'q1',
],
2 =>
[
'b' => 'y2',
'e' => 'r1',
],
];
foreach($arrB AS $arrData)
{
foreach($arrData AS $key => $val)
{
if ((isset($arrData['a']) && $arrData['a'] == $arrA[0]['a']) || (isset($arrData['b']) && $arrData['b'] == $arrA[0]['b']))
{
$arrA[0][$key] = $val;
}
elseif ((isset($arrData['b']) && $arrData['b'] == $arrA[1]['a']) || (isset($arrData['b']) && $arrData['b'] == $arrA[1]['b']))
{
$arrA[1][$key] = $val;
}
}
}
print_r($arrA);
Created the arrays similar to yours. $new_array is the resultant array that you are looking for.
$a=array();
$a[0]=array('a'=>'m1', 'b'=>'x2');
$a[1]=array('a'=>'n1', 'b'=>'y2');
$b=array();
$b[0]=array('b'=>'x2', 'c'=>'p1');
$b[1]=array('b'=>'x2', 'd'=>'q1');
$b[2]=array('b'=>'y2', 'e'=>'r1');
foreach($a as $row){
//echo '<pre>'; print_r($row);
foreach($b as $c=>$row1){
//echo '<pre>'; print_r($row1);echo $c;die;
if($row['b']==$row1['b']){
$new_array[]=array_merge($row, $row1);
}
}
}echo '<pre>'; print_r($new_array);
// Gather all values of b from both arrays
$all_b = array_unique(array_merge(array_column($arr1, 'b'), array_column($arr2, 'b')));
$res = [];
// For each b value
foreach($all_b as $b) {
$temp = [];
// Scan the arrays for items with the same b value
foreach($arr1 as $a1) {
if ($a1['b'] == $b) $temp = array_merge($temp, $a1);
}
foreach($arr2 as $a2) {
if ($a2['b'] == $b) $temp = array_merge($temp, $a2);
}
// Save them to new array
$res[] = $temp;
}
print_r($res);
demo on eval

Custom array multidim values [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I had a problem with my code. for example, I have an array like this :
[
'a' => ['f', 'g'],
'b' => ['h', 'i'],
'c' => ['j', 'k']
]
I want to change my array to be like this:
[
['a' => 'f', 'b' => 'h', 'c' => 'j'],
['a' => 'g', 'b' => 'i', 'c' => 'k']
]
I need help to solve this. Thanks
I tested this on my local computer
<?php
$array = [
'a' => ['f', 'g'],
'b' => ['h', 'i'],
'c' => ['j', 'k']
];
$ultimate_array = array();
foreach($array as $key1 => $child_array)
{
foreach($child_array as $i => $key2)
{
if(empty($ultimate_array[$i])) $ultimate_array[$i] = array();
$ultimate_array[$i][$key1] = $key2;
}
}
print_r($ultimate_array);
?>
This is a simple demonstration:
<?php
$input = [
'a' => ['f', 'g'],
'b' => ['h', 'i'],
'c' => ['j', 'k']
];
$output = [];
foreach ($input as $key=>$entries) {
foreach ($entries as $entry) {
$output[$key][] = $entry;
}
}
var_dump($output);
Some would consider this variant more elegant:
<?php
$input = [
'a' => ['f', 'g'],
'b' => ['h', 'i'],
'c' => ['j', 'k']
];
$output = [];
array_walk($input, function($entries, $key) use (&$output) {
array_walk($entries, function($entry) use (&$output, $key) {
$output[$key][] = $entry;
});
});
var_dump($output);
The obvious output of both variants is:
array(3) {
["a"]=>
array(2) {
[0]=>
string(1) "f"
[1]=>
string(1) "g"
}
["b"]=>
array(2) {
[0]=>
string(1) "h"
[1]=>
string(1) "i"
}
["c"]=>
array(2) {
[0]=>
string(1) "j"
[1]=>
string(1) "k"
}
}

Replace elements in an associative array using another associative array

How can assign the values from one array to another array? For example:
//array with empty value
$targetArray = array(
'a' => '',
'b' => '',
'c' => '',
'd' => ''
);
// array with non-empty values, but might be missing keys from the target array
$sourceArray = array(
'a'=>'a',
'c'=>'c',
'd'=>'d'
);
The result I would like to see is the following:
$resultArray = array(
'a'=>'a',
'b'=>'',
'c'=>'c',
'd'=>'d'
);
I think the function you are looking for is array_merge.
$resultArray = array_merge($targetArray,$sourceArray);
Use array_merge:
$merged = array_merge($targetArray, $sourceArray);
// will result array('a'=>'a','b'=>'','c'=>'c','d'=>'d');
Use array_merge():
$targetArray = array('a'=>'','b'=>'','c'=>'','d'=>'');
$sourceArray = array('a'=>'a','c'=>'c','d'=>'d');
$result = array_merge( $targetArray, $sourceArray);
This outputs:
array(4) {
["a"]=>
string(1) "a"
["b"]=>
string(0) ""
["c"]=>
string(1) "c"
["d"]=>
string(1) "d"
}
Perhaps a more intuitive/indicative function for this task is array_replace(). It performs identically to array_merge() on associative arrays. (Demo)
var_export(
array_replace($targetArray, $sourceArray)
);
Output:
array (
'a' => 'a',
'b' => '',
'c' => 'c',
'd' => 'd',
)
A similar but not identical result can be achieved with the union operator, but notice that its input parameters are in reverse order and the output array has keys from $targetArray then keys from $sourceArray.
var_export($sourceArray + $targetArray);
Output:
array (
'a' => 'a',
'c' => 'c',
'd' => 'd',
'b' => '',
)

Categories