Home > Software design >  Is there a optimize way to print the concatenated string which defines total no of value in a multid
Is there a optimize way to print the concatenated string which defines total no of value in a multid

Time:08-14

i have an input like this enter image description here

and i want to print the values in this format output=FA 12.9x3 FB 12.2x3 and so on i have written a code to count the occurence of value of each value but i'm unable to figure out how to print it in this format? code attached here:

  <?php
    $a=array('FA',12.9);
    $b=array('FA',12.9);
    $c=array('FB',12.2);
    $d=array('FC',12.3);
    $e=array('FA',12.9);
    $h=array('FA',12.4);
    $f=array('FB',12.9);
    //   <!-- output=  FA 12.9x2  -->
    $g=array($a,$b,$c,$d,$e,$f,$h);
    $new=[];
    $list=[];
    
    foreach ($g as $key=> $value){
        
        if(!array_key_exists($value[0],$new)){
            $new[$value[0]]=[strval($value[1])=>1];
        }
        else{
            if(!array_key_exists(strval($value[1]),$new[$value[0]])){
               $new[$value[0]][strval($value[1])]=1;
            //    $no =1;
            }
            else{
    
               $count= $new[$value[0]];
               $count=$count[strval($value[1])];
                $count =1;
                $new[$value[0]][strval($value[1])]=$count;
            }
        }
      } 
?>

so any optimized way to do it?

CodePudding user response:

Using array_reduce in a special yet useful way, we can group items by their name. Then again group by value counting each. The idea is passing along an array that accumulates the values as keys.

$g = array($a, $b, $c, $d, $e, $f, $h);

$result = array_reduce($g, function ($carry, $item) {
    $key = $item[0];
    $value = $item[1];
    if (!isset($carry[$key])) {
        $carry[$key] = [];
    }
    if (!isset($carry[$key][(string) $value])) {
        $carry[$key][(string) $value] = 0;
    }
    $carry[$key][(string) $value]  ;
    return $carry;
}, []);

print_r($result);

Output:

Array
(
    [FA] => Array
        (
            [12.9] => 3
            [12.4] => 1
        )

    [FB] => Array
        (
            [12.2] => 1
            [12.9] => 1
        )

    [FC] => Array
        (
            [12.3] => 1
        )

)

CodePudding user response:

I’m not 100% sure what your desired output is but if you collect your counts in a specific way a simple for loop might suffice.

In the below code I’m counting things in two different ways, one short version that relies on @ to suppress a warning, and one slightly longer version that explicitly looks for an initial key and sets it to 0 before incrementing.

// Count in two different but functionally identical ways
$counts_a = [];
$counts_b = [];
foreach($items as $item) {
    // Suppress the warning for missing key
    @$counts_a[$item[0] . ' ' . $item[1]]  ;
    
    // Actually look for the key and set to zero if not found
    $key = $item[0] . ' ' . $item[1];
    if(!array_key_exists($key, $counts_b)){
        $counts_b[$key] = 0;
    }
    $counts_b[$key]  ;
}

Both of those versions produce the same output which can then be looped over:

foreach($counts_a as $key => $count) {
    echo $key . 'x' . $count, PHP_EOL;
}

Demo: https://3v4l.org/hfQCK

  • Related