I have destinations array as array('destination1', 'destination2', 'destination3', 'destination4'). I want distinct combinations as
'destination1' => 'destination2'
'destination1' => 'destination3'
'destination1' => 'destination4'
'destination2' => 'destination3'
'destination2' => 'destination4'
what is the simple solution for doing this?
Did you want to do like this
$arr = array('destination1', 'destination2', 'destination3', 'destination4');
$limit = count($arr);
for($i = 0; $i < ($limit - 2); $i++){
for($j = $i + 1; $j < $limit; $j++){
echo $arr[$i].'=>'.$arr[$j].'</br>';
}
}
Improved and optimized version for any size:
while ($curr = array_shift($arr)) foreach ($arr as $item) echo $curr . '=>' . $item . '<br />';
Related
I have created an array dynamically like this way
$names = array();
for ($i = 0; $i < 100; $i++) {
$names[] = $i;
}
then created part
$parts = count($names) / 20;
and created a sub array then loop through the parts
$j = 0;
for ($i = 0; $i < $parts; $i++) {
echo "Part" . $i."<br>";
$newarray = array_slice($names, $j, 20);
for ($i = 0; $i < count($newarray); $i++) {
echo $i;
}
$j = $j + 20;
}
The problem is that this code displays from zero to 19 It doesn't display the other parts
Both the inner and outer loops use the same control variable $i, so just change the inner one...
$j = 0;
for ($i = 0; $i < $parts; $i++) {
echo "Part" . $i."<br>";
$newarray = array_slice($names, $j, 20);
for ($i1 = 0; $i1 < count($newarray); $i1++) {
echo $i1;
}
$j = $j + 20;
}
I add some Data in form of a table to my website. Actually everything works but i wanted to test the performance for some big data. It was very bad. Here my Results:
tablesize | time
-----------------
10x20 | 0.22s
100x20 | 3.29s
1000x20 | 28.75s
My question is which way is better to show the results and why:
1:
<?php
for($i=0; $i<count($array); $i++){
echo "<div id='...' class='...Ä style='...'>"
for($i=0; $i<count($array); $i++){
echo "<div style='...'>".array[$i][$j]."</div>";
}
echo "</div>";
}
?>
2:
<?php
for($i=0; $i<count($array); $i++){
?>
<div id='...' class='...Ä style='...'>
<?php
for($i=0; $i<count($array); $i++){
?>
<div style='...'> <?php echo array[$i][$j]; ?> </div>
<?php } ?>
</div>
<?php } ?>
Maybe someone has some additional tips how i can make the data visualization fast. I read some artical about MySQL structure and i believe my DB looks fine. So what i can do to optimize the reading of data.
As scaisEdge said, paginate your data.
Moreover, there are several changes that can make your code faster.
count($foo) outside of for loop
use pre-increment instead of post
use 'str' and concatenation instead of "str"
Here is a "benchmark" (without output) :
<?php
$array = array();
for($i = 0; $i < 1000; ++$i){
$array[] = range(0, 20, 1);
}
$t = microtime(true);
for($k = 0; $k < 5000; ++$k){
for($i=0; $i<count($array); $i++){
$a = "<div id='...' class='...Ä style='...'>";
for($j=0; $j<count($array[$i]); $j++){
$a = "<div style='...'>".$array[$i][$j]."</div>";
}
$a = "</div>";
}
}
echo 'Count and post : ' . (microtime(true) - $t) . "\n";
$t = microtime(true);
for($k = 0; $k < 5000; ++$k){
$c = count($array);
for($i=0; $i<$c; $i++){
$a = "<div id='...' class='...Ä style='...'>";
$c2 = count($array[$i]);
for($j=0; $j<$c2; $j++){
$a = "<div style='...'>".$array[$i][$j]."</div>";
}
$a = "</div>";
}
}
echo 'No count and post : ' . (microtime(true) - $t) . "\n";
$t = microtime(true);
for($k = 0; $k < 5000; ++$k){
$c = count($array);
for($i=0; $i<$c; ++$i){
$a = "<div id='...' class='...Ä style='...'>";
$c2 = count($array[$i]);
for($j=0; $j<$c2; ++$j){
$a = "<div style='...'>".$array[$i][$j]."</div>";
}
$a = "</div>";
}
}
echo 'No count and pre : ' . (microtime(true) - $t) . "\n";
$t = microtime(true);
for($k = 0; $k < 5000; ++$k){
$c = count($array);
for($i=0; $i<$c; ++$i){
$a = '<div id="..." class="...Ä style="...">';
$c2 = count($array[$i]);
for($j=0; $j<$c2; ++$j){
$a = '<div style="...">'.$array[$i][$j].'</div>';
}
$a = '</div>';
}
}
echo 'No count and pre and \' : ' . (microtime(true) - $t) . "\n";
// #scaisEdge
$t = microtime(true);
for($k = 0; $k < 5000; ++$k){
foreach($array as $subarray){
$a = '<div id="..." class="...Ä style="...">';
foreach($subarray as $v){
$a = '<div style="...">'.$v.'</div>';
}
$a = '</div>';
}
}
echo 'Foreach : ' . (microtime(true) - $t) . "\n";
?>
This outputs :
Count and post : 46.050459861755
No count and post : 30.590306043625
No count and pre : 29.880299091339
No count and pre and ' : 29.930299043655
Foreach : 29.120290994644
As weird as it looks, ' seems to be slower than ".
PHP checks " strings variables inside and replace it whereas ' string are just... string. No operation performed.
Has someone an idea of this slowness ?
For large output you should use pagination ... output 1000 rows seems not useful
If you paginate your result is more equal to the firts that to the last .
But you can do somethings for the code .. you should count the result just one time and not for all cycle of the loop
so instead of for($i=0; i<count($array); $i++){
you should use
$numElem =count($array);
for($i=0; $i<$numElem; $i++){
.......
}
or use
foreach ( $array as $key => $value ){
......
}
these are much faster
I have this array :
$products = array('0', '1', '2', '3');
and I want to have this combination :
0
0,1
0,1,2
0,1,2,3 // my code can't show this result
0,1,3 // my code can't show this result
0,2
0,2,3
0,3
1
1,2
1,2,3
1,3
2
2,3
3
and here's my code :
$rows = count($products);
for ($i = 0; $i < $rows; $i++) {
echo $i . '<br>';
for ($j = $i + 1; $j < $rows; $j++){
echo $i . $j . '<br>';
if (!empty($products[$j+1])) {
echo $i . $j . $products[$j+1] . '<br>';
}
}
}
but, unfortunately I missed 2 results :
0,1,2,3
0,1,3
and I still have doubt about this for loop inside loop, while the number of combination is determined by array length.
how to get that missed combination and perfectly works for different array length?
$products = array('0', '1', '2', '3');
$rows = count($products); //missing here array count......
for ($i = 0; $i < $rows; $i++) {
echo $i . '<br>';
for ($j = $i + 1; $j < $rows; $j++){
echo $i . $j . '<br>';
if (!empty($products[$j+1])) {
echo $i . $j . $products[$j+1] . '<br>';
}
}
}
Try this
<?php
$set = array('0', '1', '2','3');
$power_set = possible_set($set);
echo "<pre>";
print_r($power_set);
echo "</pre>";
function possible_set($array) {
$results = array(array( ));
foreach ($array as $element)
foreach ($results as $inner_element)
array_push($results, array_merge(array($element), $inner_element));
unset($results[0]);
$results = array_values($results);
return $results;
}
?>
https://eval.in/516963
I wanted to have a way to get all combinations for all given numbers with given array length.
In my project the array size usually is 7. So I write a test code like this to see if I can get all needed combinations. The important part is every result array must be unique and maximum array size must be 7.
<?php
$numbers = [1, 2, 3, 4, 5, 6, 7];
$arraysize = 7;
$subset = [];
$count = count($numbers);
for ($i = 0; $i < $count; $i++) {
$subset[] = $numbers[$i];
}
for ($i=0; $i < $count; $i++) {
for ($j=$i; $j < $count; $j++) {
$subset[] = $numbers[$i] . $numbers[$j];
}
}
for ($i=0; $i < $count; $i++) {
for ($j=$i; $j < $count; $j++) {
for ($k=$j; $k < $count; $k++) {
$subset[] = $numbers[$i] . $numbers[$j] . $numbers[$k];
}
}
}
for ($i=0; $i < $count; $i++) {
for ($j=$i; $j < $count; $j++) {
for ($k=$j; $k < $count; $k++) {
for ($l=$k; $l < $count; $l++) {
$subset[] = $numbers[$i] . $numbers[$j] . $numbers[$k] . $numbers[$l];
}
}
}
}
for ($i=0; $i < $count; $i++) {
for ($j=$i; $j < $count; $j++) {
for ($k=$j; $k < $count; $k++) {
for ($l=$k; $l < $count; $l++) {
for ($m=$l; $m < $count; $m++) {
$subset[] = $numbers[$i] . $numbers[$j] . $numbers[$k] . $numbers[$l] . $numbers[$m];
}
}
}
}
}
for ($i=0; $i < $count; $i++) {
for ($j=$i; $j < $count; $j++) {
for ($k=$j; $k < $count; $k++) {
for ($l=$k; $l < $count; $l++) {
for ($m=$l; $m < $count; $m++) {
for ($n=$m; $n < $count; $n++) {
$subset[] = $numbers[$i] . $numbers[$j] . $numbers[$k] . $numbers[$l] . $numbers[$m] . $numbers[$n];
}
}
}
}
}
}
for ($i=0; $i < $count; $i++) {
for ($j=$i; $j < $count; $j++) {
for ($k=$j; $k < $count; $k++) {
for ($l=$k; $l < $count; $l++) {
for ($m=$l; $m < $count; $m++) {
for ($n=$m; $n < $count; $n++) {
for ($o=$n; $o < $count; $o++) {
$subset[] = $numbers[$i] . $numbers[$j] . $numbers[$k] . $numbers[$l] . $numbers[$m] . $numbers[$n] . $numbers[$o];
}
}
}
}
}
}
}
echo "<pre>";
print_r($subset);
echo "</pre>";
?>
When I run this code I get the combinations like I wanted (I make the combinations as string to see the results clearly but normally every result item in $subset array must be array)
With this code I can get all unique combinations.
But as you can see this code is ugly. I tried to make this a recursive function but I failed. Could anyone point me to right direction to get the exact same results like this? (every item in $subset array normally must be an array that contains digits)
You can simplify this logic (and make the code less ugly) without needing to go recursive by using:
for ($i = 0; $i < $count; $i++) {
$subset[] = $numbers[$i];
for ($j=$i; $j < $count; $j++) {
$subset[] = $numbers[$i] . $numbers[$j];
for ($k=$j; $k < $count; $k++) {
$subset[] = $numbers[$i] . $numbers[$j] . $numbers[$k];
for ($l=$k; $l < $count; $l++) {
$subset[] = $numbers[$i] . $numbers[$j] . $numbers[$k] . $numbers[$l];
}
}
}
}
the following will work in all cases even if you have duplicate numbers in your array
$array = array(1,2,3,4,5,6,7,8,9,10,11,12,13,14);
sort($array); //in case it 's not sorted
$array = array_slice($array,-7);
$num = count($array );
$total = pow(2, $num);
$result= array();
$element='';
for ($i = 0; $i < $total; $i++)
{
for ($j = 0; $j < $num; $j++)
{
if (pow(2, $j) & $i)
{
$element=$element.$array [$j];
}
}
$result[]=$element;
$element='';
}
print_r($result);
This implementation returns all the combinations of all items (77 = 823542 combinations of 7 items):
function combine_all(array $numbers) {
$count = count($numbers);
$result = array_map('strval', $numbers);
for($i = 1; $i < $count; ++$i) {
$combinations = array_slice($result, pow($count, $i-1));
foreach($numbers as $number) {
foreach($combinations as $combination) {
$result[] = $number . ',' . $combination;
}
}
}
return $result;
}
When using print_r to output the data, it can perform very slowly:
$array = array_fill(0, pow(7,7), '');
$t = microtime(true);
echo '<pre>';
print_r($array);
echo '</pre>';
echo microtime(true) - $t;
// 0.75329303741455
$t = microtime(true);
echo '<pre>';
print_r( combine_all(array(1,2,3,4,5,6,7)) );
echo '</pre>';
echo microtime(true) - $t;
// 1.7037351131439
$t = microtime(true);
combine_all(array(1,2,3,4,5,6,7));
echo microtime(true) - $t;
//0.75869607925415
To restrict the items number, use the array_slice function:
combine_all(array_slice($numbers, 0, 7));
If you really want a recursive function, you could do something like this:
function combine_all(array $numbers, $cnt=null, $baseCombination=null) {
if( $baseCombination === null ) {
$cnt = count($numbers);
}
if( $cnt > 0 ) {
$result = array();
foreach($numbers as $number) {
$combination = $number . ',' . $baseCombination;
$result[] = $combination;
$result = array_merge($result, combine_all($numbers, $cnt-1, $combination));
}
return $result;
}
return array();
}
But it takes too much memory.
I finally found out a way to add recursive function to create unique combinations from given numbers:
$numbers = [1, 2, 3, 4, 5, 6, 7];
function subsetSumRecursive($numbers, $arraySize, $level = 1, $i = 0, $addThis = [])
{
// If this is the last layer, use a different method to pass the number.
if ($level == $arraySize) {
$result = [];
for (; $i < count($numbers); $i++) {
$result[] = array_merge($addThis, array($numbers[$i]));
}
return $result;
}
$result = [];
$nextLevel = $level + 1;
for (; $i < count($numbers); $i++) {
// Add the data given from upper level to current iterated number and pass
// the new data to a deeper level.
$newAdd = array_merge($addThis, array($numbers[$i]));
$temp = subsetSumRecursive($numbers, $arraySize, $nextLevel, $i, $newAdd);
$result = array_merge($result, $temp);
}
return $result;
}
echo "<pre>";
print_r(subsetSumRecursive($numbers, 7));
echo "</pre>";
I want to save value from looping in an array. Then I want to sort it to numerically desc.
here is my code
<?php
$n = 5;
for ($i = 0 ; $i < $n ; $i++){
$a = $i + 1;
echo $a;
} // the result is 1,2,3,4,5. How can I do sorting so the result will be 5,4,3,2,1?
?>
Simply flip the loop:
<?php
$n = 5;
// the for loop now starts at $n and will decrease $i by 1 after every loop
for ($i = $n ; $i > 0 ; $i--){
echo $i;
} // the result is 5,4,3,2,1
?>
function desc($n){
$arr = array();
for ($i = 1 ; $i <= $n ; $i++){
array_push($arr,$i);
}
$arr = array_reverse($arr);
foreach ($arr as $key => $value) {
echo $value . " => ";
}
}
desc(5); // output 5 => 4 => 3 => 2 => 1
PS. In this way you are saving values in array as well
<?php
$array = array();
$n = 5;
for ($i = 0 ; $i < $n ; $i++){
array_push($array,($i+1));
}
$array = array_reverse($array);
for($i = 0 ; $i < sizeof($array) ; $i++)
echo $array[$i].'<br>';
?>