简体   繁体   中英

php count occurences of an array field and increment the value of another field to print rows associated to ID

Hello everybody Im getting headache at this question here asked before then I try now to solve in other way. Ihave a script that loops an array that put data in a CSV file, i need to count the rows with same ID and put the row number line by line.

this is my scritpt that loops the array and put it in a csv file for export.

public function fputToFile($file, $allexportfields, $object, $ae)
{
    if($allexportfields && $file && $object && $ae)
    {
        //one ready for export product
        $readyForExport = array();

            //put in correct sort order
            foreach ($allexportfields as $value)
            {
                $object = $this->processDecimalSettings($object, $ae, $value);
                $readyForExport[$value] = iconv("UTF-8", $ae->charset, $object[$value]);

            }
                //write into csv line by line
        fputcsv($file, $readyForExport, $ae->delimiter, $ae->separator);
    }
}

Is its possible to use array_count_values(); to count the occurences of $value['id_order'] and increment a variable line by line ? when $value['id_order'] changes we must reset to 1.

the result sould exit like this exportet to csv file:

order_ID num_row
176 1
177 1
177 2
178 1
178 2
179 1
179 2
180 1
181 1
181 2
182 1
182 2
183 1
184 1
184 2
185 1
185 2
186 1
186 2
186 3

Many thanks to everyone.

EDIT I have edited the code as suggested by Nigel Ren, it seems to be a good solution but I think I'm missing something. Still does not print anything in my variable...

            //one ready for export product
        $readyForExport = array();

            //put in correct sort order
            foreach ($allexportfields as $value)
            {
                $object = $this->processDecimalSettings($object, $ae, $value);
                $readyForExport[$value] = iconv("UTF-8", $ae->charset, $object[$value]);

            //$dati_csv = $readyForExport[$value];
            //echo " <script type=\"text/javascript\">alert('$dati_csv')</script>";
            }


            $orders = array();
            $orders = $readyForExport['id_order'];
            $lastOrder = null;    // Variable to track previous order
            $orderLine = null;    // the line number added

            foreach ( $orders as &$order )   {
                // If first time round or the order_ID isn't the same as last time
                 if ( $lastOrder === null || $lastOrder != $order["order_ID"])   {
                    $orderLine = 1;
                    $lastOrder = $order["order_ID"];
                    }
                // Add in the orderLine column
                $order['orderLine'] = $orderLine++;
            }
            print_r($orders);

            $readtForExport['num_row'] = $orderds;

EDIT I Put the fopen(); function where it writes to file as asked by Nigel:

public function writeToFile($ae, $sorted_fields, $elements)
{
    $url = $this->getFileUrl($ae->filename, $ae->type);

    $file = @fopen( $url, 'w' );
    //add labels for export data
    if($ae->add_header)
        $this->filewrite($ae, $sorted_fields, $file);

    $i = 0;
    while ($element = $this->nextRow($elements))
    {
        if ($i == $this->rowsNumber - 1)
        {
            $this->lastElement = $element;
        }

        Configuration::updateGlobalValue("AdvancedExport_CURRENT", (string)$i);
        //progress bar
        $this->getDataFromObject($element, $file, $sorted_fields, $ae);
        $i++; //progress bar
    }

    //close file
    if($file)
        fclose($file);

    return $url;
}

If you have a list of all of the orders in the correct order_ID order, you can just keep a track of the last order_id processed and reset a line number when it changes...

// A mini set of test data
$orders = [["order_ID" => 1],
        ["order_ID" => 2],
        ["order_ID" => 2],
        ["order_ID" => 3],
        ["order_ID" => 3],
        ["order_ID" => 3],
        ["order_ID" => 4]];


$lastOrder = null;    // Variable to track previous order
$orderLine = null;    // the line number added
foreach ( $orders as &$order )   {
    // If first time round or the order_ID isn't the same as last time
    if ( $lastOrder === null || $lastOrder != $order["order_ID"])   {
        $orderLine = 1;
        $lastOrder = $order["order_ID"];
    }
    // Add in the orderLine column
    $order['orderLine'] = $orderLine++;
}
print_r($orders);

This outputs...

Array
(
    [0] => Array
        (
            [order_ID] => 1
            [orderLine] => 1
        )

    [1] => Array
        (
            [order_ID] => 2
            [orderLine] => 1
        )

    [2] => Array
        (
            [order_ID] => 2
            [orderLine] => 2
        )

    [3] => Array
        (
            [order_ID] => 3
            [orderLine] => 1
        )

    [4] => Array
        (
            [order_ID] => 3
            [orderLine] => 2
        )

    [5] => Array
        (
            [order_ID] => 3
            [orderLine] => 3
        )

    [6] => Array
        (
            [order_ID] => 4
            [orderLine] => 1
        )

)

Update:

To keep all of the processing in the fputToFile() method, I've resorted to using static fields to hold the previous values. This means that the values will be kept as long as the code is running. This also means that this may not work if you try and export more than one file at a time.

public function fputToFile($file, $allexportfields, $object, $ae)
{
    if($allexportfields && $file && $object && $ae)
    {
        //one ready for export product
        $readyForExport = array();

        static $lastOrder = null;    // Variable to track previous order
        static $orderLine = null;    // the line number added
        if ( $lastOrder === null || $lastOrder != $allexportfields["order_ID"])   {
            $orderLine = 1;
            $lastOrder = $allexportfields["order_ID"];
        }

        //put in correct sort order
        foreach ($allexportfields as $value)
        {
            $object = $this->processDecimalSettings($object, $ae, $value);
            $readyForExport[$value] = iconv("UTF-8", $ae->charset, $object[$value]);

        }

        // Add in the orderLine column
        $readyForExport[] = $orderLine++;

        //write into csv line by line
        fputcsv($file, $readyForExport, $ae->delimiter, $ae->separator);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM