What I need
I need all possible pairs of n elements without duplicates. Let's say I've these arrays:
$arr1 = [2, 4, 6, 7];
$arr2 = [6, 5, 4, 11];
$arr3 = [22, 1, 5, 8];
$final = [
'a' => $arr1,
'b' => $arr2,
'c' => $arr3
];
What I now need is:
$pairs = [
'ab' => [$arr1, $arr2],
'ac' => [$arr1, $arr3],
'bc' => [$arr2, $arr3]
];
What I got
I come until this point:
function getPairs($array) {
$n = count($array);
$finalArray = [];
$i = 0;
foreach ($array as $a) {
for ($x = $n-1; 0 <= $x; $x--) {
if ($i != $x) {
$finalArray[] = [$array[$i], $array[$x]];
}
}
$i++;
}
return $finalArray;
}
And then:
$arr1 = [2, 4, 6, 7];
$arr2 = [6, 5, 4, 11];
$arr3 = [22, 1, 5, 8];
$merged = [$arr1, $arr2, $arr3];
$pairs = getPairs($merged);
There are two problems with my approach:
The loop produces $x = 0, $i = 1 and later $i = 1, $x = 0, which results and a duplicated array.
I don't get the keys (ab, ac, cb) with this.
Similiar to this question but with array keys: Get all the combinations of N elements of multidimensional array
To avoid duplicates, guarantee that one member of the pair always has the "lower" key. This will avoid getting pairs ac and ca.
To get the letter keys you want, use array_keys() to extract the keys from the original arrays.
function getPairs($array) {
$n = count($array);
$keys = array_keys($array);
$finalArray = [];
$i = 0;
foreach ($array as $a) {
for ($x = $n-1; $i < $x; $x--) {
$key1 = $keys[$i];
$key2 = $keys[$x];
$finalArray[$key1.$key2] = [$array[$key1], $array[$key2]];
}
$i++;
}
return $finalArray;
}
Live demo
This code should work if I understand the task properly:
$a = [[2, 4, 6, 7],[6, 5, 4, 11],[22, 1, 5, 8]];
$result = [];
$n = count($a);
for($i = 0; $i < $n-1; $i++) {
for($j = $i+1; $j < $n; $j++) {
$result[(string)$i.(string)$j] = [$a[$i], $a[$j]];
}
}
print_r($result);
Here is a "hybrid" of the other two answers:
$arr1 = [2, 4, 6, 7];
$arr2 = [6, 5, 4, 11];
$arr3 = [22, 1, 5, 8];
$final = [
'a' => $arr1,
'b' => $arr2,
'c' => $arr3
];
$n = count($final);
$keys = array_keys($final);
$pairs = [];
for($i = 0; $i < $n-1; $i++) {
for($j = $i+1; $j < $n; $j++) {
$pairs[$keys[$i] . $keys[$j]] = [$final[$keys[$i]], $final[$keys[$j]]];
}
}
print_r($pairs);
Related
There are two arrays:
$arrOne = [1, 3, 4];
$arrTwo = [2, 5,];
$newArr = [];
How to merge to get like this;
$newArr = [1, 2, 3, 4, 5];
Now displays through one, this option is not suitable.
foreach ($arrOne as $k => $v) {
$newArr[] = $v;
$newArr[] = $arrTwo[$k];
}
Here is another example. Tthe values can be different in the array.
$arrOne = [154, 32, 15];
$arrTwo = [682, 124,];
Again for this example it is necessary that the values from the second array always be at 2 and 5 positions in the new array:
$newArr = [154, 682, 32, 15, 124];
You can use array_splice to merge the arrays in the intended way to the specific indices:
array_splice( $arrOne, 1, 0, $arrTwo[0]);
array_splice( $arrOne, 4, 0, $arrTwo[1]);
var_dump($arrOne);
Demo 1:
Using original data:
$arrOne = [1, 3, 4];
$arrTwo = [2, 5,];
https://3v4l.org/dAMav
Demo 2:
Using second set of data:
$arrOne = [154, 32, 15];
$arrTwo = [682, 124,];
https://3v4l.org/Xhl3K
You can use array_merge and sort functions to achieve this as following:
$newArr = array_merge($arrOne, $arrTwo); // it will be [1, 3, 4, 2, 5]
sort($newArr); // it will sort array [1, 2, 3, 4, 5]
You can use $newArr now which have sorted data
$arrOne = [1, 3, 4];
$arrTwo = [2, 5];
$newArr = [];
foreach($arrOne as $key => $one) {
switch($key) {
case 1:
$newArr[] = $arrTwo[0];
break;
case 4:
$newArr[] = $arrTwo[1];
break;
}
$newArr[] = $one;
}
if(count($newArr) < 5) {
$newArr[] = $arrTwo[1];
}
Demo link
Here we are considering there will be always two elements in second array
$arrayOne = [12,23,45,56,65,78,99];
$arrayTwo = [2,5];
$mergedArray = [];
foreach($arrayOne as $key => $value) {
$position = $key + 1;
if ($position === 2) {
$mergedArray[] = $arrayTwo[0];
} else if ($position === 4) {
$mergedArray[] = $arrayTwo[1];
}
$mergedArray[] = $value;
}
I have two different arrays like this
$array1 = [1, 2, 8, 10];
$array2 = [2, 4, 6, 8, 10, 15, 1];
I want to get the common elements and uncommon elements between them.
I almost figured out how to get the common ones as the code below but I can't get uncommon elements.
for($x = 0; $x < count($array1); $x++) {
for($z = 0; $z < count($array2); $z++) {
if ( $array1[$x] == $array2[$z] ) {
$array3 = $array1[$x];
print_r($array3);
} elseif ($array1[$x] !== $array2[$z]) {
// code...
}
}
}
How to get those uncommon or different elements between the two arrays without using a built-in PHP method then output them in a new array.
You can get the uncommon elements by using in_array() function
<?php
$array1 = [1, 2, 8, 10];
$array2 = [2, 4, 6, 8, 10, 15, 1];
$result = [];
for($i = 0;$i < sizeof($array2);$i++){
if(!in_array($array2[$i],$array1)){
$result[] = $array2[$i];
}
}
?>
Output
Array
(
[0] => 4
[1] => 6
[2] => 15
)
$names = ['john','brian','john','steven','michael','paul','mark','paul','brian'];
$money = [2, 4, 3, 7, 5, 8, 20, -2, 4];
The indexes of $names and $money correspond to each other.
I need to find the most efficient way to add common $money to each $names and print only the even values.
For example, john appears two times, with 2 and 3 money. So johnhas 5 money.
Desired output:
mark: 20
brian: 8
paul: 6
I am thinking of looping through each array, but this is O(n^2) Is there an easier way?
Make associative array (hash) for result:
$names = ['john','brian','john','steven','michael','paul','mark','paul','brian'];
$money = [2, 4, 3, 7, 5, 8, 20, -2, 4];
$result = [];
for ($i = 0; $i < count($names); $i++) {
if (!isset($result[$names[$i]])) {
$result[$names[$i]] = 0;
}
$result[$names[$i]] += $money[$i];
}
arsort($result); // reverse (big first) sort by money
print_r($result);
just loop through names and use it keys for money array:
$names = ['john','brian','john','steven','michael','paul','mark','paul','brian'];
$money = [2, 4, 3, 7, 5, 8, 20, -2, 4];
$res = [];
foreach ($names as $key => $value) {
$res[$value] = isset($res[$value]) ? $res[$value] + $money[$key] : $money[$key];
}
var_dump($res);
You just have to loop through $names once and set name as key in a result- variable.
$names = ['john','brian','john','steven','michael','paul','mark','paul','brian'];
$money = [2, 4, 3, 7, 5, 8, 20, -2, 4];
$data = [];
foreach ($names as $key => $name) {
if (!isset($data[$name])) {
$data[$name] = 0;
}
$data[$name] += $money[$key];
}
print_r($data);
Maybe you'll need a check, if both arrays have the same size.
$names = ['john','brian','john','steven','michael','paul','mark','paul','brian'];
$money = [2, 4, 3, 7, 5, 8, 20, -2, 4];
$result = [];
foreach ($names as $index => $name) {
if (empty($result[$name]) {
$result[$name] = $money[$index];
} else {
$result[$name] += $money[$index];
}
}
print_r($result);
I have two random arrays merged, everything displaying/functioning beautifully. The one stuck I have is this:
When I merge the two arrays together I need to make sure that every 3 item comes from array2.
array1 (a,b,c,d,e,f,g,h,i,j,k)
array2 (a1,a2,a3,a4)
My desired outcome:
d k c a1 j i g a2 etc.
What I have done so far:
function randomize_blocks($arr, $num = 1) {
shuffle($arr);
$r = array();
for ($i = 0; $i < $num; $i++) {
$r[] = $arr[$i];
}
return $num == 1 ? $r[0] : $r;
}
//gather donor blocks into an array
$donorBlocks = array($blockA, $blockB, $blockC, $blockD, $blockE, $blockF,
$blockG, $blockH, $blockI, $blockJ, $blockK, $blockL, $blockM, $blockN,
$blockO);
//gather value blocks into an array
$valueBlocks = array($valueA, $valueB, $valueC, $valueD);
//shake that shuffler real hard! DT
$shuffled_valueBlocks = randomize_blocks($valueBlocks, 4);
$shuffled_donorBlocks = randomize_blocks($donorBlocks, 15);
//combine our shuffled arrays together
$combinedArrays = array_merge($shuffled_valueBlocks, $shuffled_donorBlocks);
//shuffle them all together!
$shuffled_blocks = randomize_blocks($combinedArrays, 19);
//display bocks on page
foreach ($combinedArrays as $key => $value) {
echo $value;
}
What is the best way to accomplish this?
Here is a way with array_splice to modify the longest of the two arrays into the desired result:
$a = ['a', 'b', 'c', 'd'];
$b = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
foreach ($a as $i => $v)
array_splice($b, $i*4+3, 0, [$v]);
$b will be:
[1, 2, 3, 'a', 4, 5, 6, 'b', 7, 8, 9, 'c', 10, 11, 12, 'd', 13, 14, 15]
What about something like this?
$a1 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'];
$a2 = ['a1', 'a2', 'a3', 'a4'];
$a = [];
shuffle($a1);
foreach ($a1 as $k => $v) {
$a[] = $v;
if (($k + 1) % 3 === 0 && $a2) $a[] = array_shift($a2);
}
This is based on the assumption that you want both arrays shuffled as well as placed in your desired pattern:
$array_one = array('a','b','c','d','e','f','g','h','i','j','k');
$array_two = array('a1','a2','a3','a4');
function merge_random_interval($array_one = array(), $array_two = array(), $interval = 3) {
$return_array = array();
// Shuffle the arrays - that seems to be important?
shuffle($array_one);
shuffle($array_two);
// Go through the first array
$array_two_index = 0;
for ($i = 0; $i < count($array_one); $i++) {
// Every $interval add a value from the second array
if ($i > 0 && $i % $interval == 0) {
// Make sure there is a value in the second array
if (isset($array_two[$array_two_index])) {
$return_array[] = $array_two[$array_two_index];
$array_two_index++;
}
}
$return_array[] = $array_one[$i];
}
// You may want to check if $array_two has more values that weren't added?
// Compare $array_two_index against count($array_two)
return $return_array;
}
$result_array = merge_random_interval($array_one, $array_two, 3);
echo implode(' ', $result_array); // g d c a1 h i j a4 b e a a2 k f
This question already has answers here:
Transpose and flatten two-dimensional indexed array where rows may not be of equal length
(4 answers)
Insert elements from one array (one-at-a-time) after every second element of another array (un-even zippering)
(5 answers)
Closed 10 months ago.
I need a function that can intersect 2 arrays for example:
$Array1 = array(1,2,3);
$Array2 = array(5,6);
and results in:
array(1,5,2,6,3);
What I have so far is this
<?php
$Array1 = array(1,2,3);
$Array2 = array(5,6);
function zip() {
$args = func_get_args();
$zipped = array();
$n = count($args);
for ($i=0; $i<$n; ++$i) {
reset($args[$i]);
}
while ($n) {
$tmp = array();
for ($i=0; $i<$n; ++$i) {
if (key($args[$i]) === null) {
break 2;
}
$tmp[] = current($args[$i]);
next($args[$i]);
}
$zipped[] = $tmp;
}
return $zipped;
}
$bothMonths = zip($Array1, $Array2);
print_r($bothMonths);
?>
that have the output like
Array (
[0] => Array (
[0] => 1
[1] => 5
)
[1] => Array (
[0] => 2
[1] => 6
)
)
I don't know why 3 is missing.
Also I need pure programming, forget about array_merge, array_intersect ... or other functions.
// Interleaves arbitrarily many input arrays. Example:
// a1 = [1, 2, 3], a2 = [5, 6], a3 = [7, 8, 9]
// zip(a1, a2, a3) => [1, 5, 7, 2, 6, 8, 3, 9]
function zip() {
$arrays = func_get_args();
$result = array();
// Count the length of the arrays to get the length of the longest
$longest = array_reduce($arrays, function($old, $e) {
return max($old, count($e));
}, 0);
// Traverse the arrays, one element at a time
for ($i = 0; $i < $longest; $i++) {
foreach($arrays as $a) {
if (isset($a[$i]))
$result[] = $a[$i];
}
}
return $result;
}
This assumes that your arrays are numerically indexed from 0 and up.
Try this:
function custom_intersect($arr1, $arr2) {
$len1 = count($arr1);
$len2 = count($arr2);
$max_len = ($len1 >= $len2) ? $len1 : $len2;
$arr = array();
for($i = 0; $i < $max_len; ++$i)
{
if(isset($arr1[$i]))
{
$arr[] = $arr1[$i];
}
if(isset($arr2[$i]))
{
$arr[] = $arr2[$i];
}
}
return $arr;
}