0

I know there are a lot of topics about this, but just couldn't find any that would actually help me solve the problem. Ok so i am having a problem with counting rows and values in multidimensional array (imported via .csv)

enter image description here

I am trying to achieve something like...

Array ( [0] => Array ( [0] => 1 [1] => 6278,31 [2] => 4) 
        [1] => Array ( [0] => 2 [1] => 2,0 [2] => 2) 
        [2] => Array ( [0] => 3 [1] => 3,01 [2] => 3) 
         )

where [0] would be buyer id, 1 is total number of buys and [2] total cost.

My current code:

if(($s_open = fopen("sales.csv", "r")) !== FALSE) 
    {
        $s_count = count(file("sales.csv"));
        while(($sales = fgetcsv($s_open, 100, ";")) !== FALSE) 
        {
            ...
        }
        fclose($s_open);
    }

Thanks in advance.

3 Answers 3

1

You could group your data by creating an array with the buyer_id as index.

Each time you find a new buyer, you could create a small array ('id','count','amount').

Then, sum the values of the current row into that array.

const KEY_ID     = 0; // shortcut for array indexes
const KEY_AMOUNT = 1;
const KEY_COUNT  = 2;


$buyers = []; // final array

if (($s_open = fopen("sales.csv", "r")) !== FALSE) 
{
    $s_count = count(file("sales.csv"));
    while(($sales = fgetcsv($s_open, 100, ";")) !== FALSE) 
    {
        // Extract data from row:
        [$id, $buyer_id, , $amount] = $sales;
        
        // If the buyer doesn't exists in the array,
        // create a new array with required format:
        if (!isset($buyers[$buyer_id])) {
            $buyers[$buyer_id] = [
                KEY_ID     => $buyer_id, 
                KEY_COUNT  => 0, 
                KEY_AMOUNT => 0,
            ];
        }
        
        // Update values:
        $buyers[$buyer_id][KEY_COUNT]++;
        $buyers[$buyer_id][KEY_AMOUNT] += $amount;
    }
    fclose($s_open);
}

// Re-index values:
$buyers = array_values($buyers);
Sign up to request clarification or add additional context in comments.

7 Comments

is it somehow possible to parse to float $buyers[$buyer_id][KEY_AMOUNT]. floatval doesn't do it for me :S Thanks btw, you are a life saver :)
Float strings are treated as float by using a mathematical operator (here +=). See 3v4l.org/CSlOf. But, you could cast as float like this : $buyers[$buyer_id][KEY_AMOUNT] += (float)$amount;?
still no decimal points. either way it stays like an integer :S
Could you var_dump($amount) in the loop? What are the printed values?
var_dump returns float. Is it possible to change / parse "const KEY_AMOUNT = 2" to float?
|
0

Using this mock data in.csv:

id, buyer_id, amount
1, 1, 100.55
2, 1, 500.1
3, 2, 50.55
4, 3, 1.0

I wrote the following PHP to parse it into a nicely formatted array (if you don't want to have named keys, you can just remove the header logic):

<?php

// Each line into an array
$csv = file(__DIR__ . DIRECTORY_SEPARATOR . 'in.csv');

// First line is the header
$header = str_getcsv(array_shift($csv));

// When the CSV header is `id, buyer_id, amount`, remove the whitespace
$header = array_map(function ($item) {
    return trim($item);
}, $header);

// Get the CSV data as an array of arrays
$out = array_map(function ($line) use ($header) {
    $data = str_getcsv($line);
    return array_combine($header, $data);
}, $csv);

print_r($out);

Which prints the following to your screen:

Array
(
    [0] => Array
        (
            [id] => 1
            [buyer_id] =>  1
            [amount] =>  100.55
        )

    [1] => Array
        (
            [id] => 2
            [buyer_id] =>  1
            [amount] =>  500.1
        )

    [2] => Array
        (
            [id] => 3
            [buyer_id] =>  2
            [amount] =>  50.55
        )

    [3] => Array
        (
            [id] => 4
            [buyer_id] =>  3
            [amount] =>  1.0
        )

)

Comments

0

Try this

$data = [];
if(($s_open = fopen("sales.csv", "r")) !== FALSE) {
    $s_count = count(file("sales.csv"));
    while( ([$id, $buyer_id, $amount] = fgetcsv($s_open, 100, ";")) !== FALSE ){
        if( $id !== 'id' ){
            $data[$buyer_id] = [
                $buyer_id,
                ($data[$buyer_id][1] ?? 0) + 1,
                ($data[$buyer_id][2] ?? 0) + $amount
            ];
        }
    }
    fclose($s_open);
    $data = array_values($data);
}
// print_r($data);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.