This question already has answers here:
Finding cartesian product with PHP associative arrays
(10 answers)
Closed 5 years ago.
i want combine 2 array like this
Example 1 :
Arr1 = ['A','B','C'],
Arr2 = ['D','E']
will be become
Arr3 = [
['A','D'],['A','E'],['B','D'],['B','E'],['',''] ....
]
Example 2 :
Arr1 = ['A','B','C'],
Arr2 = ['D','E']
Arr3 = ['G','H']
will be become
Arr4 = [
['A','D','G'],['A','E','G'],['','','']....
]
Any idea or suggest me algorithm can be like this thanks so much
Simplified version; merging array by index
$arr1 = range('a', 'b');
$arr2 = range('c', 'f');
$arr3 = range('g', 'k');
$arr4 = range('x', 'z');
$res = array();
// $counter = 1;
// while ($counter <= 4) {
// $array = "arr{$counter}";
// funcIndexMerge($res, $$array);
// $counter++;
// }
funcIndexMerge($res, $arr1);
funcIndexMerge($res, $arr2);
funcIndexMerge($res, $arr3);
funcIndexMerge($res, $arr4);
var_export($res);
function funcIndexMerge(&$res, $array) {
foreach ($array as $ari => $val) {
if (!isset($res[$ari])) {
$res[$ari] = array();
}
$res[$ari] = array_merge($res[$ari], array($val));
}
}
The problem you suggest is very similar to this Leetcode Challenge. The idea is to use Backtracking
Psuedo PsedoCode :
result := string Array
CartesianProduct(rowIndex, ArrayList, stringSoFar):
if rowIndex equal ArrayList.size:
Add stringSoFar to result
return
for(eachItem in ArrayList[rowIndex])
CartesianProduct(rowIndex +1 , ArrayList, stringSoFar + eachItem)
return
This is a workhorse which does all the computation and can be called like CartesianProduct(0, list of Array to be multiplied, "")
Suppose your ArrayList = [['A'], ['C', 'D']]. And CP be CartesianProduct
CP(0, AL, "")
(Take 'A')/
/
CP(1, AL, "A") (stringSoFar becomes 'A')
(Take C) / \(Take 'D'.Second Iteration with second array['C', 'D'])
/ \
CP(2, AL, "AC") CP(2, AL, "AD")
/ \
rowIndex equal size. rowIndex equals listSize i.e No more list to look
Add "AC" and return Add stringsoFar ("AD") to result and rerturn
My solution to the Leetcode problem(but in C++). Hopefully it'll give you some idea to write in PHP
class Solution {
public:
map<char, vector<string>> values {
{'2', vector<string>{"a", "b", "c"}},
{'3', vector<string>{"d", "e", "f"}},
{'4', vector<string>{"g", "h", "i"}},
{'5', vector<string>{"j", "k", "l"}},
{'6', vector<string>{"m", "n", "o"}},
{'7', vector<string>{"p", "q", "r", "s"}},
{'8', vector<string>{"t", "u", "v"}},
{'9', vector<string>{"w", "x", "y", "z"}}
};
vector<string> answer;
void doComb(int index, string digits, string sofar)
{
if(index == digits.size())
{
if(sofar != "")
{
answer.push_back(sofar);
}
return;
}
for(auto lett : values[digits[index]])
{
doComb(index + 1, digits, sofar + lett);
}
return;
}
vector<string> letterCombinations(string digits) {
doComb(0, digits, "");
return answer;
}
};
Related
How to extract only Numbers from an Array?
$myarray = array("A","B", "2","D");
I want to get numeric values ("2" in this example) from an array to a variable
You can use is-numeric and array-filter (PHP build-in functions):
$myarray = array("A", "B", "2", "D", "3");
$b = array_filter($myarray, "is_numeric");
Now $b is an array containing the strings: 2 and 3.
Edited Regarding your comment: if you have only 1 value and you want to add 10 to it you can do:
$myarray = array("A", "B", "2", "D");
$b = array_filter($myarray, "is_numeric");
$c = array_values($b); //reset the keys
$finalvalue = $c[0] + 10; // will output 12
<?php
$input = array('A','B', '2.2','D');
foreach($input as $v)
is_numeric($v) && $nums[] = $v;
// Take the first numeric found and add 10.
$result = isset($nums[0]) ? $nums[0] + 10 : null;
var_dump($result);
Output:
float(12.2)
This question already has answers here:
fastest way to find if all the elements of an array are distinct?
(4 answers)
Closed 6 years ago.
I have this array:
$number = array("a", "b", "b", "c", "a", "b", "c", "b", "c");
Now I want to get all unique values. Means the result should be:
$result = array("a", "b", "c");
Now I know that this can easily be solved with array_unique(). But I want to write my own little implementation of array_unique() just using a for loop, unset() and array_values().
Something like this maybe? Here we are looping through and array starting in one for from the position 0 and in the other from 1. We compare the $i position with all the others in array and if it finds two same it removes the second one.
<?php
$number = array("a", "b", "b", "c", "a", "b", "c", "b", "c");
$count = count($number);
for($i = 0; $i < $count; $i++) {
for($j = $i+1; $j < $count; $j++) {
if(isset($number[$j]) && isset($number[$i]) && $number[$i] == $number[$j]) {
unset($number[$j]);
}
}
}
print_r($number);
use array_unique()
<?php
$number=array("a","b","b","c","a","b","c","b","c");
$unique_array=array_unique($number);
print_r($unique_array);
?>
//second posibility
<?php
$number=array("a","b","b","c","a","b","c","b","c");
$unique_array=[];
foreach($number as $val)
{
$unique_array[$val]=$val;
}
print_r(array_values($unique_array));
?>
//Third posibility with for,unset,array_value
<?php
$number=array("a","b","b","c","a","b","c","b","c");
$count=count($number);
for($i=0;$i<$count;$i++)
{
if($i<count($number))
{
for($j=$i+1;$j<$count;$j++)
{
if($number[$i]==$number[$j])
{
unset($number[$j]);
}
}
}
}
$number=array_values($number);
print_r($number);
?>
expected result is
Array ( [0] => a [1] => b [2] => c )
This question already has answers here:
Transposing multidimensional arrays in PHP
(12 answers)
Closed 2 years ago.
For example if a matrix is:
1 2
3 4
5 6
Then transpose of above matrix will be:
1 3 5
2 4 6
This is my current code:
<?php
// transpose matrix
$trans = array(
array(1, 2),
array(3, 4),
array(5, 6)
);
foreach ($trans as $key => $val){
foreach ($trans[$key] as $k => $v){
echo $v;
}
}
?>
There's a quirky PHP way to transpose a 2d array:
$trans = array(
array(1, 2),
array(3, 4),
array(5, 6)
);
array_unshift($trans, null);
$trans = call_user_func_array('array_map', $trans);
var_dump($trans);
Demo
EDIT Easier approach using PHP 5.6 array unpacking
With the introduction of the array argument unpacking feature in PHP 5.6, we can simplify this still further:
$trans = array(
array(1, 2),
array(3, 4),
array(5, 6)
);
$trans = array_map(null, ...$trans);
var_dump($trans);
EDIT Explanation
Quoting from the PHP docs for the array_map() function:
An interesting use of this function is to construct an array of arrays, which can be easily performed by using NULL as the name of the callback function
(See Example #4 from that docs page for an example of what this does)
The array_unshift($trans, null) that we perform first is providing that NULL callback, and we use call_user_func_array() because we don't necessarily know how many values there are in our $trans array. What we're doing using that call_user_func_array() is the equivalent of:
$trans = array_map(NULL, $trans[0], $trans[1], $trans[2]);
for your example array, because the top-level of your 2-d array has three elements (keys 0, 1 and 2).
Effectively, this NULL callback loops through all the arrays in parallel taking each value from them in turn to build a new array:
$maxArraySize = max(count($array[0], $array[1], $array[2]);
// $maxArraySize will have a value of 2 in your case,
// because your sub-arrays are all equal size
$newArray = [];
for($i = 0; $i < $maxArraySize; ++$i) {
$tmpArray = [];
$tmpArray[] = $array[0][$i];
$tmpArray[] = $array[1][$i];
$tmpArray[] = $array[2][$i];
$newArray[] = $tmpArray[];
}
There's a couple of extra checks in there
it doesn't care if your arrays are associative or enumerated in either dimension, because it accesses the $ith element, not the index
If the sub-arrays aren't all the same length, then it effectively pads the shorter sub-arrays with null values to match the length of the longest
It doesn't matter how many arrays you pass in, it will work with them all in parallel
I believe this works with rectangular arrays as well.
The trick: return array_map(null, ...$squareArray); seems to work in an unexpected way for a single column array
function RotateSquare2DArray($squareArray)
{
if ($squareArray == null) { return null; }
$rotatedArray = array();
$r = 0;
foreach($squareArray as $row) {
$c = 0;
if (is_array($row)) {
foreach($row as $cell) {
$rotatedArray[$c][$r] = $cell;
++$c;
}
}
else $rotatedArray[$c][$r] = $row;
++$r;
}
return $rotatedArray;
}
If the array is associative, I use this
function RotateSquareAssociativeArray($squareArray)
{
if ($squareArray == null) { return null; }
$rotatedArray = array();
$r = 0;
foreach($squareArray as $c=>$row) {
if (is_array($row)) {
foreach($row as $key=>$cell) {
$rotatedArray[$key][$c] = $cell;
}
}
else {
$rotatedArray[$c][$r] = $row;
}
++$r;
}
return $rotatedArray;
}
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 7 years ago.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Original close reason(s) were not resolved
Improve this question
I have 19 variables in a php file.
$a = 20;
$b = 23;
$c = 2;
$d = 92;
$e = 51;
$f = 27;
$g = 20;
$h = 20;
.....
.....
$s = 32;
What i need, I need to show only top 5 value. And there is similar value for some variables. In that case, I need to show the first value only if it is in the top 5 value.
I am not having any clue on doing this.
After receiving some feedback given bellow, i have used array and asort
Here is the example-
<?php
$fruits = array("a" => "32", "b" => "12", "c" => "19", "d" => "18");
asort($fruits);
foreach ($fruits as $key => $val) {
echo "$key = $val\n";
}
?>
The output looks like this:
b = 12 d = 18 c = 19 a = 32
I need the reverse result. Meaning, 32, 19, 18, 12.....
Any help. Just dont know the exact command
This is best done by putting the values of the variables into an array and running
sort($arr); (this is from lowes to highest).
rsort($arr); sorts high to low.
http://php.net/manual/en/array.sorting.php
Then you can get the first values at array-index 0,1,2,3 and 4 which will be the biggest numbers.
So:
$arr= array ($a,$b,$c, ....);
rsort($arr);
var_dump($arr); // gives the output.
$arr[0] // biggest number
$arr[4] // 5th biggest number.
A funny way to do this:
$a = 20;
$b = 23;
$c = 2;
$d = 92;
$e = 51;
$f = 27;
$g = 20;
$h = 20;
$array = compact(range('a', 'h'));
rsort($array);
foreach(array_slice($array, 0, 5) as $top) {
echo $top, "\n";
}
Output
92
51
27
23
20
Demo: http://3v4l.org/Wi8q7
Do they need to be individual variables? Storing the values in an array is a better option. So, either manually put all the variables into an array, or change your structure to something more like:
$arr = array(
'a' = 20,
'b' = 23,
'c' = 2,
'd' = 92,
'e' = 51,
....
....
's' => 32
);
or similar. Then use sort() to sort the array:
sort($arr);
To get the top 5, use array_slice():
$arr = array_slice($arr, 0, 5);
See demo
Note: sort() may not be best option for you depending on the desired result. For other sorting options, consult the manual: http://php.net/manual/en/array.sorting.php
<?php
array_push($data,$a);
array_push($data,$b);
.
.
.
$sorted_array = usort($data, 'mysort');
$top5 = array_splice($sorted_array,5);
if(in_array($your_variable,$top5)){
return $top5[0];
}else {
return $top5;
}
function mysort($a,$b){
if ($a == $b) {
return 0;
}
return ($a < $b) ? 1 : -1;
}
?>
$array=array();
for ($i=97;$i<=115;$i++){ //decimal char codes for a-s
$var =chr($i);
$array[]= $$var; //variable variable $a- $s
}
asort($array);
var_dump($array);
Sorry for my bad English and thanks for your help in advance! I have kind of a tricky problem I've encountered while coding. Here's the point:
I need a script that essentially extracts the 5 max values of 5 arrays, that are "mixed", i.e. they contain "recurrent" values. Here is an example:
array1(a, b)
array2(a, c, d, e, g)
array3(b, d, g, h)
array4(e, t, z)
array5(b, c, d, k)
The 2 essential requests are:
1) the sum of those 5 arrays (array1+array2+array3...) MUST be the highest possible...
2) ...without repeat ANY value previously used** (e.g. if in array1 the top value was "b", this cannot be re-used as max value in arrays 3 or 5).
Currently I have this...:
$group1 = array(a, b);
$group = array(a, b, c, d);
$max1a = max(group1);
$max2a = max(group2) unset($max1a);
$sum1 = $max1a + $max2a;
$max2b = max(group2);
$max1b = max(group1)
unset($max2b);
$sum2 = $max1b + $max2b;
if($sum1 > $sum2) {
echo $sum1
} else {
echo $sum2
}
... but it's kinda impossible to use this code with 5 arrays, because I should compare 5! (120...!!!) combinations in order to find the max sum value.
I know the problem is quite difficult to explain and to solve, but I really need your help and I hope you can save me!!!
Cheers
I'm adding this as another answer to leave the previous one intact for someone coming across this looking for that variation on this behaviour.
Given the 2 arrays:
$array1 = array(30, 29, 20);
$array2 = array(30, 20, 10);
The maximum sum using one element from each is 59 - this is dramatically different to my previous approach (and the answers' of others) which took the max element of the first array and then the highest element of the next array that is not equal to any previously used value - this would give 50 instead.
The code you want is this:
$mainArray = array();
$mainArray[] = array(30, 29, 20);
$mainArray[] = array(30, 20, 10);
$tempArray = array();
$newArray = array();
foreach($mainArray as $innerArray) {
$newArray = array();
if (count($tempArray) == 0) {
foreach ($innerArray as $value) {
$newArray[] = array('total' => $value, 'used' => array($value));
}
}
else {
foreach ($tempArray as $key => $innerTempArray) {
$placed = FALSE;
foreach ($innerArray as $value) {
if (!(in_array($value, $innerTempArray['used']))) {
$newArray[] = array('total' => $tempArray[$key]['total'] + $value, 'used' => $tempArray[$key]['used']);
$newArray[count($newArray) - 1]['used'][] = $value;
$placed = TRUE;
}
}
if (!($placed)) {
echo "An array had no elements that had not already been used";
die();
}
}
}
$tempArray = $newArray;
}
$total = 0;
if (count($newArray) == 0) {
echo "No data passed";
die();
}
else {
$total = $newArray[0]['total'];
}
for ($i = 0; $i < count($newArray); $i++) {
if ($newArray[$i]['total'] > $total) {
$total = $newArray[$i]['total'];
}
}
var_dump($total);
EDIT - Do not repeat used variables (but repeated values are ok):
Let
//$a = 30, $b = 30, $c = 25, $d = 20, $e = 19
$array1 = array($a, $c, $d);
$array2 = array($b, $d, $e);
We want to choose $a from $array1 and $b from $array2 as these give the largest sum - although they're values are the same that is allowed because we only care if the names of the variables saved to that place are the same.
With the arrays in the above format there is no way of achieving the desired behaviour - the arrays do not know what the name of the variable who's value was assigned to their elements, only it's value. Therefore we must change the first part of the original answer to:
$mainArray[] = array('a', 'c', 'd');
$mainArray[] = array('b', 'd', 'e');
and also have either the of the following before the first foreach loop (to declare $a, $b, $c, $d, $e)
//either
extract(array(
'a' => 30,
'b' => 30,
'c' => 25,
'd' => 20,
'e' => 19
));
//or
$a = 30; $b = 30; $c = 25; $d = 20; $e = 19;
The above both do exactly the same thing, I just prefer the first for neatness.
Then replace the line below
$newArray[] = array('total' => $value, 'used' => array($value));
with
$newArray[] = array('total' => ${$value}, 'used' => array($value));
The change is curly brackets around the first $value because that is then evaluated to get the variable name to use (like below example):
$test = 'hello';
$var = 'test';
echo ${$var}; //prints 'hello'
A similar change replaces
$newArray[] = array('total' => $tempArray[$key]['total'] + $value, 'used' => $tempArray[$key]['used']);
with
$newArray[] = array('total' => $tempArray[$key]['total'] + ${$value}, 'used' => $tempArray[$key]['used']);
Now the code will function as wanted :)
If you are dynamically building the arrays you are comparing and can't build the array of strings instead of variables then there is no way to do it. You would need some way of extracting "$a" or "a" from $a = 30, which PHP is not meant to do (there are hacks but they are complicated and only work in certain situations (google "get variable name as string in php" to see what I mean)
If by the top value you mean the first alphabetically then the following would work:
$array1 = array('a', 'b');
$array2 = array('a', 'c', 'd', 'e', 'g');
$array3 = array('b', 'd', 'g', 'h');
$array4 = array('e', 't', 'z');
$array5 = array('b', 'c', 'd', 'k');
$mainArray = array($array1, $array2, $array3, $array4, $array5);
foreach ($mainArray as $key => $value) {
sort($mainArray[$key]);
}
$resultArray = array();
foreach($maniArray as $key1 => $value1) {
$placed = FALSE;
foreach ($value1 as $value2) {
if (!(in_array($value2, $resultArray))) {
$resultArray[] = $value2;
$placed = TRUE;
break;
}
}
if (!($placed)) {
echo "All the values in the " . ($key + 1) . "th array are already max values in other arrays";
die();
}
}
var_dump($resultArray);
I'm not sure, of i really understood your problem correctly, these are my assumptions:
You have five arrays containing numbers
These numbers can occur multiple times across the arrays
You want to find the highest possible sum of elements across your arrays
The sum uses one single value of each array
But the sum must not use the same number twice
Is that correct?
If Yes, then:
The highest possible sum across all arrays is always the sum of the largest elements. If you do not want to use the same number twice, you can just get the maximum from the first array, remove it from all the others and then sum up all the remaining maxima.
Like so:
$arrays = array();
$arrays[] = array(1, 2);
$arrays[] = array(1, 3, 4, 5, 7);
$arrays[] = array(2, 4, 7, 8);
$arrays[] = array(5, 20, 26);
$arrays[] = array(2, 3, 4, 11);
for($i=0, $n=count($arrays); $i<$n; $i++) {
if($i===0) {
$a1max = max($arrays[$i]);
$sum = $a1max;
} else {
$duplicate_pos = array_search($a1max, $arrays[$i]);
if($duplicate_pos !== FALSE) {
unset($arrays[$i][$duplicate_pos]);
}
$sum += max($arrays[$i]);
}
}
echo "sum: " . $sum . "\n";
Assuming you have grouped together all your values in one array like this,
$array = array(
array(1,2,3),
array(1,2,3,4),
array(1,2,3,4,5,6),
array(1,2,3,4,5,6),
array(1,2,3,4,5,6,7)
);
Loop through $array, and get the highest value which has not been used previously,
$max = array();
foreach($array as $value)
$max[] = max(array_diff($value, $max));
Calculate the sum of all values with array_sum(),
echo "The maximal sum is: ".array_sum($max);