I need to get all the combinations and permutations of an array of array of values. See snippet for example:
$a = array(
1,
2
);
$b = array(
'foo',
'bar'
);
$params = array();
$params[] = $a;
$params[] = $b;
// What to do to $params so I can get the following combinations/permutations?
// 1,foo
// 2,foo
// 1,bar
// 2,bar
// foo,1
// bar,1
// foo,2
// bar,2
Keep in mind that the $params can be any size and the items in it can also be any size.
function all($array, $partial, &$result) {
if ($array == array()) {
$result[] = implode(',', $partial);
return;
}
for($i=0; $i<count($array);$i++) {
$e = $array[$i];
$a = $array;
array_splice($a, $i, 1);
foreach($e as $v) {
$p = $partial;
$p[] = $v;
all($a, $p, $result);
}
}
}
Test:
$a = array(1, 2, 3);
$b = array('foo', 'bar');
$c = array('a', 'b');
$params = array($a, $b, $c);
$result = array();
all($params, array(), $result);
print_r($result);
Note: if there is a chance for duplicates (arrays contain the same values) you can check for duplicates before inserting into the $result.
Here is my solution. It should work with any number of associative arrays, even if they contained nested associative arrays.
<?php
$a = array(1,2,3);
$b = array('foo','bar','baz', array('other','other2',array('other3','other4')));
$params = array();
$params[] = $a;
$params[] = $b;
$elements = array();
foreach($params as $param) {
addElement($param,$elements);
}
function addElement($arg,&$result) {
if(!is_array($arg)) {
$result[] = $arg;
} else {
foreach($arg as $argArray) {
addElement($argArray,$result);
}
}
}
for($i=0; $i<count($elements); $i++) {
$curElement = $elements[$i];
for($j=0; $j<count($elements); $j++) {
if($elements[$j] != $curElement) {
$final_results[] = $curElement.','.$elements[$j];
}
}
}
print_r($final_results);
?>
http://codepad.viper-7.com/XEAKFM
Here's a possible solution codepad...
$array = array(
0 => array(
'foo',
'bar'
),
1 => array(
1,
2,
3
),
2 => array(
'x',
'y',
'z'
),
3 => array(
7,
8,
9
)
);
array_permutations($array, $permutations);
print_r($permutations);
public function array_permutations($array, &$permutations, $current_key = 0, $current_subkey = 0)
{
if(!isset($array[$current_key][$current_subkey]))
{
return;
}
$current_val = $array[$current_key][$current_subkey];
foreach($array as $array_key => $row)
{
foreach($row as $row_key => $sub_val)
{
if($array_key === $current_key)
{
if($row_key !== $current_subkey)
{
$permutations[] = $current_val . ', ' . $sub_val;
}
}
else
{
$permutations[] = $current_val . ', ' . $sub_val;
}
}
}
$next_key = ($current_subkey == (count($array[$current_key]) - 1)) ? $current_key + 1 : $current_key;
$next_subkey = ($next_key > $current_key) ? 0 : $current_subkey + 1;
array_permutations($array, $permutations, $next_key, $next_subkey);
}
Try this out, hope this helps
$a = array(
1,
2,
4
);
$b = array(
'foo',
'bar',
'zer'
);
$c = array(
'aaa',
'bbb'
);
$params = array();
$params[] = $a;
$params[] = $b;
$params[] = $c;
$sizeofp = count($params);
for($i=0 ; $i < $sizeofp ; $i++){
foreach ($params[$i] as $paramA) {
for($j=0 ; $j < $sizeofp ; $j++){
if($j == $i){
continue;
}
foreach($params[$j] as $paramB){
echo "\n".$paramA.",".$paramB;
}
}
}
}
Related
I registered two query varaible 'star' & 'cord'
And when I visit https://website.com/blog/star-4-5/cord-Corded/
and use $star = explode( '-', get_query_var('star', '') );
$star output is shows as
Array ( [0] => 4 [1] => 5/cord [2] => Corded )
and $cord output is shows as 'Empty'
While $star should show Array ( [0] => 4 [1] => 5 )
and $cord should show 'Corded '
function trimmer_register_query_vars( $vars ) {
$vars[] = 'brand';
$vars[] = 'price';
$vars[] = 'water';
$vars[] = 'star';
$vars[] = 'cord';
return $vars;}add_filter( 'query_vars', 'trimmer_register_query_vars' );
Here's written rule I used for it, it automatically rewrite a combination of all queries.
function generate_rewrite_rules($keys) {
$total_keys = count($keys);
$rules = array();
for ($i = 1; $i <= $total_keys; $i++) {
$combinations = combinations($keys, $i);
foreach ($combinations as $combination) {
$rule = '^trimmer/';
$query = 'index.php?post_type=trimmer&';
$j = 1;
foreach ($combination as $key) {
$rule .= $key . '-(.+?)/'; // Use non-greedy match (`.+?`) instead of greedy match (`.+`)
$query .= $key . '=$matches[' . $j . ']&';
$j++;
}
$rule = rtrim($rule, '/');
$rule .= '/?$';
$query = rtrim($query, '&');
$rules[] = array(
'rule' => $rule,
'query' => $query,
'top' => true
);
}
}
return $rules;
}
function combinations($keys, $length) {
if ($length == 1) {
return array_map(function($val) {
return array($val);
}, $keys);
}
$result = array();
for ($i = 0; $i < count($keys) - $length + 1; $i++) {
$head = $keys[$i];
$combos = combinations(array_slice($keys, $i + 1), $length - 1);
foreach ($combos as $combo) {
array_unshift($combo, $head);
$result[] = $combo;
}
}
return $result;
}
add_action('init', 'register_trimmer_rules');
function register_trimmer_rules() {
$keys = array('brand', 'price', 'cord', 'water', 'star');
$rules = generate_rewrite_rules($keys);
foreach ($rules as $rule) {
add_rewrite_rule($rule['rule'], $rule['query'], $rule['top']);
}
}
I have an $array and a $number, and I want to find the smallest combination (least number of elements) of the $array's elements, which sums to the $number, but I can't figure out how to do this with PHP code.
Test cases:
$array = [
'a' => '1',
'b' => '3',
'c' => '5',
'd' => '5',
'e' => '1',
'f' => '2',
'g' => '2',
];
If $number = 10, output should be 'c', 'd'
If $number = 1, output should be either 'a' or 'e'
If $number = 4, output should be either 'a', 'b' or 'b', 'e' or 'f', 'g'
If $number = 9 output should be 'a', 'b', 'c' or 'a', 'b', 'd' or 'c', 'f', 'g' etc.
How can I write this in code?
try this ( and use Recursive Algorithm )
<?php
$array= array("a"=>"1", "b"=>"3", "c"=>"5", "d"=>"5", "e"=>"1", "f"=>"2","g"=>"2");$num=6;
foreach ($array as $key => $value) {
if ($value==$num){
echo $key."=>".$value."<br>";
}
echo "-----------------"."<br>";
foreach( $array as $key1 => $value1) {
if($key1 > $key){
if(sumval($value,$value1)==$num){
echo $key."=>".$key1."<br>";
}
elseif(sumval($value,$value1)<$num){
$total=sumval($value,$value1);
foreach( $array as $key2 => $value2) {
if($key2 > $key1){
if(sumval($total,$value2)==$num){
echo $key."=>".$key1."=>".$key2."<br>";
}
}
}
}
}
}
}
function sumval($a,$b){
return $a+$b;
}
?>
You can try something like this
<?php
$array = ["a"=>"1", "b"=>"3", "c"=>"5", "d"=>"5", "e"=>"1", "f"=>"2", "g"=>"2"];
$new = $array;
$number = 19;//Change here to check all condition
$flag = false;
if(array_sum($new) == $number){
$temp = array_keys($new);
echo implode(",",$temp);
$flag = true;
exit;
}
if($flag)
exit;
foreach($array as $key=>$value){
if($value == $number){
echo $key."\n";
$flag = true;
exit;
}
}
if($flag)
exit;
foreach($array as $key=>$value){
$new = $array;
array_pop($new);
foreach($new as $key2=>$value2){
if($key!=$key2){
if(($value + $value2) == $number){
echo "$key , $key2 \n";
$flag = true;
exit;
}
}
}
}
if($flag)
exit;
$new = $array;
foreach($array as $key1=>$value1){
foreach($array as $key=>$value){
$new = $array;
unset($new[$key]);
if(array_sum($new) == $number){
$temp = array_keys($new);
echo implode(",",$temp);
exit;
}
array_pop($new);
}
array_pop($array);
}
?>
Live demo : https://eval.in/897632
Try this?
<?php
$array= array("a"=>"1", "b"=>"3", "c"=>"5", "d"=>"5", "e"=>"1", "f"=>"2", "g"=>"2");
$num = 4;
foreach ($array as $key => $value) {
$n1 = (int) $value;
if ($n1 === $num) {
echo $key.'<br/>';
break;
}
if ($n1 < $num) {
$n2 = $num - $n1;
if ($n2Key = isN2Exists("$n2", $array)) { // this probably can also be done using some PHP built-ins, but I just couldnt find the right one
echo "$key,$n2Key <br/>";
}
}
}
function isN2Exists($value, $array) {
foreach ($array as $k => $v) {
if ($v === $value) {
return $k;
}
}
return false;
}
This wont work if you need more than 2 numbers. For example, if the number is 9, you can not produce 9 with two numbers in your array. You need a,b,c or c,f,g. If you want it that way I think best way to do is to use recursion.
Update
If you want to do it through recursion, please try the following code. This should give you the exact output you are looking for:
<?php
$array= array("a"=>"1", "b"=>"3", "c"=>"5", "d"=>"5", "e"=>"1", "f"=>"2", "g"=>"2");
$num = 9;
function getLeastNumbers($num, $array, $sum = 0, $level = '', $resultSet = [], $combination = []) {
if ($sum > $num) {
return false;
}
foreach ($array as $key => $value) {
$n1 = (int) $value;
if (($n1 + $sum) == $num) {
$newCombination = $combination;
$newCombination[] = $key;
sort($newCombination);
$resultSet[] = $newCombination;
}
$combinationToSend = $combination;
$combinationToSend[] = $key;
sort($combinationToSend);
$array2 = $array;
unset($array2[$key]);
if ($return = getLeastNumbers($num, $array2, $n1 + $sum, "$level .", $resultSet, $combinationToSend)) {
$resultSet = array_unique(array_merge($resultSet, $return), SORT_REGULAR);
}
}
return $resultSet;
}
$list = getLeastNumbers($num, $array);
foreach($list as $item) {
$length = count($item);
$finalArray[$length][] = $item;
}
print_r($finalArray[min(array_keys($finalArray))]);
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);
I have an array which contains 3 different arrays.
$arrayAll = (
0 => $array1,
1 => $array2,
2 => $array3
);
How can I loop through $arrayAll, displaying the first element of each sub-array(array1,array2,array3) on each itteration?
So, the output will be:
$array1[0],$array2[0],$array3[0],
$array1[1],$array2[1],$array3[1],
$array1[2],$array2[2],$array3[2]
and so on.. until all sublements are fetched.
EDIT:
$addsContent = $Adds->selectAdds(10);
$sharedArticlesContent = $SharedContent->getSharedContent($topic_selected, $filter_selected);
$blogPostsContent = $BlogPosts->getRecentBlogPostsByTopic("business");
$contentArray = array(
$sharedArticlesContent,
$addsContent ,
$blogPostsContent
);
foreach($contentArray as $value)
{
if(count($value)>$maxLength)
{
$maxLength = count($value);
}
}
for($i=0; $i<$maxLength; $i++)
{
foreach($contentArray as $value)
{
if(isset($value[$i]))
{
if($value==$sharedArticlesContent){
$data = $value[$i];
foreach($sharedArticlesContent as $data){
$post_id = $data['id'];
$uploaded_by = $data['uploaded_by'];
$text = $data['text'];
$image = $data['image'];
require 'template1.php';
}
}elseif($value==$addsContent){
//template2
}else{
//template3
}
}
}
}
$maxLength = 0;
foreach($arrayAll as $value)
{
if(count($value)>$maxLength)
{
$maxLength = count($value);
}
}
for($i=0; $i<$maxLength; $i++)
{
foreach($arrayAll as $value)
{
if(isset($value[$i]))
{
echo $value[$i];
}
}
}
I was trying to access GCD from inside Algorithm but it's not letting me and I'm not sure why. What am I doing wrong here?
public function gcd($x,$y)
{
do {
$rest=$x%$y;
$x=$y;
$y=$rest;
} while($rest!==0);
return $x;
}
public function algorithm()
{
$alpha = array(
'c' => str_split('bcdfghjklmnpqrstvwxz'),
'v' => str_split('aeiouy')
);
$i=$k=0;
foreach ($this->output as $item) {
$cnt = 0;
$this->digits[$i] = array();
foreach ($item as $part) {
$this->digits[$i][$cnt] = array();
$new = array();
foreach ($part as $str) {
$v = count(array_intersect(str_split($str), $alpha['v']));
$c = count(array_intersect(str_split($str), $alpha['c']));
$t = strlen(str_replace(' ', '', $str));
$new = ($cnt == 0)
? array('v' => $v, 'c' => $c, 't' => $t, 'm' => ($t%2) ? $v * 1.5 : $c)
: array('v' => $v, 'c' => $c, 't' => $t);
$this->digits[$i][$cnt][] = $new;
}
$cnt++;
}
$i++;
}
$h=$a=0;
foreach($this->digits as &$etc) {
foreach($etc[0] as &$r){
foreach($etc[1] as $k) {
foreach($k as $x=>$y) {
$tmp[$h] = (gcd($y,$r['t']) != 1) ? ++$a:'';
}
$tmp[$h] = $r['m']*$a*1.5;
$h++;
$a=0;
}$h=0;
$r['f'] = $tmp;
$tmp='';
}
}
foreach($this->digits as &$u){unset($u[1]);}
}
judging by your use of the public identifier, I would guess your two functions are in a class.
To refer to methods on the same object, use $this->methodname()
from your code:
$tmp[$h] = (gcd($y,$r['t']) != 1) ? ++$a:'';
should be:
$tmp[$h] = ($this->gcd($y,$r['t']) != 1) ? ++$a:'';
...
$this->gcd()?
But really, since gcd doesn't use any member variables, it should be a free function.
You're missing $this->gcd inside algorithm
just tryng to acces it direct
:)