-1

I have a nested loop like this

foreach ($subdistricts as $subdistrict) {
    $originId = $subdistrict->id;
    $exist[] = $originId; 
    foreach($subdistricts as $subdistrict) {
        if(($originId != $subdistrict->id) || (!in_array($subdistrict->id,$exist))) {
            $destinationId = $subdistrict->id;
            echo 'from: '.$originId.' to: ' .$destinationId;
        }
    }
}

let's say I have data id like this = 244,255,266

I want the results be like:

from '244' to '255'

from '244' to '266'

from '255' to '266'

instead, I only got:

from '244' to '255'

from '244' to '266'

the $subdistricts :

Cake\ORM\Query Object
(
    [(help)] => This is a Query object, to get the results execute or iterate it.
    [sql] => SELECT Subdistricts.id AS `Subdistricts__id`, Subdistricts.name AS `Subdistricts__name`, Subdistricts.city_id AS `Subdistricts__city_id` FROM subdistricts Subdistricts WHERE Subdistricts.city_id = :c0
    [params] => Array
        (
            [:c0] => Array
                (
                    [value] => 17
                    [type] => integer
                    [placeholder] => c0
                )

        )

    [defaultTypes] => Array
        (
            [Subdistricts__id] => integer
            [Subdistricts.id] => integer
            [id] => integer
            [Subdistricts__name] => string
            [Subdistricts.name] => string
            [name] => string
            [Subdistricts__city_id] => integer
            [Subdistricts.city_id] => integer
            [city_id] => integer
        )

    [decorators] => 1
    [executed] => 1
    [hydrate] => 1
    [buffered] => 1
    [formatters] => 0
    [mapReducers] => 0
    [contain] => Array
        (
        )

    [matching] => Array
        (
        )

    [extraOptions] => Array
        (
        )

    [repository] => App\Model\Table\SubdistrictsTable Object
        (
            [registryAlias] => Subdistricts
            [table] => subdistricts
            [alias] => Subdistricts
            [entityClass] => App\Model\Entity\Subdistrict
            [associations] => Array
                (
                    [0] => cities
                )

            [behaviors] => Array
                (
                )

            [defaultConnection] => default
            [connectionName] => default
        )

)

the $subdistrict :

App\Model\Entity\Subdistrict Object
(
    [id] => 258
    [name] => Abiansemal
    [city_id] => 17
    [[new]] => 
    [[accessible]] => Array
        (
            [*] => 1
        )

    [[dirty]] => Array
        (
        )

    [[original]] => Array
        (
        )

    [[virtual]] => Array
        (
        )

    [[errors]] => Array
        (
        )

    [[invalid]] => Array
        (
        )

    [[repository]] => Subdistricts
)
Idham Choudry
  • 589
  • 10
  • 31

3 Answers3

0

Assuming that your data is [244,255,266] you can use this piece of codes. I copied it from here.

function combination_number($k,$n){
    $n = intval($n);
    $k = intval($k);
    if ($k > $n){
        return 0;
    } elseif ($n == $k) {
        return 1;
    } else {
        if ($k >= $n - $k){
            $l = $k+1;
            for ($i = $l+1 ; $i <= $n ; $i++)
                $l *= $i;
            $m = 1;
            for ($i = 2 ; $i <= $n-$k ; $i++)
                $m *= $i;
        } else {
            $l = ($n-$k) + 1;
            for ($i = $l+1 ; $i <= $n ; $i++)
                $l *= $i;
            $m = 1;
            for ($i = 2 ; $i <= $k ; $i++)
                $m *= $i;            
        }
    }
    return $l/$m;
}

function array_combination($le, $set){

    $lk = combination_number($le, count($set));
    $ret = array_fill(0, $lk, array_fill(0, $le, '') );

    $temp = array();
    for ($i = 0 ; $i < $le ; $i++)
        $temp[$i] = $i;

    $ret[0] = $temp;

    for ($i = 1 ; $i < $lk ; $i++){
        if ($temp[$le-1] != count($set)-1){
            $temp[$le-1]++;
        } else {
            $od = -1;
            for ($j = $le-2 ; $j >= 0 ; $j--)
                if ($temp[$j]+1 != $temp[$j+1]){
                    $od = $j;
                    break;
                }
            if ($od == -1)
                break;
            $temp[$od]++;
            for ($j = $od+1 ; $j < $le ; $j++)    
                $temp[$j] = $temp[$od]+$j-$od;
        }
        $ret[$i] = $temp;
    }
    for ($i = 0 ; $i < $lk ; $i++)
        for ($j = 0 ; $j < $le ; $j++)
            $ret[$i][$j] = $set[$ret[$i][$j]];

    $res = json_decode(json_encode($ret), false);
    return $res;
}

In your case, the usage is as follow

$data = [244,255,266];

$result = array_combination(2, $data);
for($i=0;$i<count($result);$i++)
{
    print "from ".$result[$i][0]." to ".$result[$i][1]."\n";
}

Output

from 244 to 255
from 244 to 266
from 255 to 266
Community
  • 1
  • 1
michael
  • 33
  • 3
0
foreach ($subdistricts as $subdistrict){
    $originId = $subdistrict->id;
    $exist[] = $originId; 
    foreach($subdistricts as $subdistrict_1){
        if(($originId != $subdistrict_1->id) || in_array($subdistrict_1->id,$exist))){
           $destinationId = $subdistrict_1->id;
           echo 'from: '.$originId.' to: ' .$destinationId;
        }
    }
}

You can try with this code bacause in your code $subdistrict variable is conflict in second foreach.

Mandip Vora
  • 309
  • 1
  • 2
  • 14
0
  1. Since you're using foreach, it's creating/using the variables $subdistrict twice and it gets overwritten, so you need to change either one (I changed the nested one to $subdistrict_1).
  2. In the if statement, you are validating it isn't the same OR it isn't in the array, while you need it to not be the same AND not be in the array.

    foreach ($subdistricts as $subdistrict) {
        $originId = $subdistrict->id;
        $exist[] = $originId; 
    
        foreach($subdistricts as $subdistrict_1){
            if( ($originId != $subdistrict_1->id) && !in_array($subdistrict_1->id, $exist) ) {
                $destinationId = $subdistrict_1->id;
                echo 'from: '.$originId.' to: ' .$destinationId;
            }
        }
    }
    
SrQ
  • 106
  • 7