0

I'm having a peculiar issue. I have a CSV file that has Comma Separated Values that I need to upload and then get Nested Array of values based on following 3 conditions;

  1. The array will first loop through all values and get first 4 unique characters. (Codes)
  2. Match each column values with the with number of columns in each row and give count of rows that matches 4 digit codes. (Single_Devices for single column and Dual, Triple and Quad for respective columns count)
  3. Match each column values with code and list all the columns under the Devices. (Numbers)

CSV file

123429000000000
123429000000001
123429000000010,123429000000011
123429000000040,123429000000041

What I desire is;

Array
(
    [Code] => 1234
        (
            [single_devices] => 2
                (
                    [0] => Array
                        (
                            [0] => 123429000000000
                        )
                    [1] => Array
                        (
                            [0] => 123429000000001
                        )
                )
            [dual_devices] => 2
                (
                    [0] => Array
                        (
                            [0] => 123429000000010
                            [1] => 123429000000011
                        )
                    [1] => Array
                        (
                            [0] => 123429000000040
                            [1] => 123429000000041
                        )
                )
        )

)

Is it possible? I can manage JSON converted data or object or just associative nested array.

Edit: This is the code I wrote for which was only showing values and not indexes as I desired.

// Get all numbers in array
for ($j = 0; $j < count($csv_file[$i]); $j++){
    $numbers[] = $csv_file[$i][$j];
}

// Get codes from numbers
for ($i = 0; $i < count($csv_file); $i++){
    for ($j = 0; $j < count($csv_file[$i]); $j++){
        $codes[] = substr($csv_file[$i][$j], 0, 4);
    }
}

// Get unique codes from codes array
$codes = array_unique($codes);

// Get numbers and sort them codes and device count wise.
for ($i = 0; $i < count($csv_file); $i++){
    for ($j = 0; $j < count($csv_file[$i]); $j++){
        $q = count($csv_file[$i]); // set device count based on column count
        if (count($csv_file[$i]) == $q){ // if device count is equal to column count
            foreach ($codes as $code){ // loop through unique codes
                if ($code == substr($csv_file[$i][$j], 0, 4)){ // if number's first 4 char matches code
                    // create array with code and then device count and add numbers
                    $devices[$code][$q.'_device_numbers'][$i][$j] = preg_replace('/\s+/', '', $csv_file[$i][$j]);
                }
            }
        }
    }
}

This is what I am getting from the above code.

Array
(
    [1234] => Array
        (
            [1_sim_imeis] => Array
                (
                    [0] => Array
                        (
                            [0] => 123429000000000
                        )

                    [1] => Array
                        (
                            [0] => 123429000000001
                        )

                )

            [2_sim_imeis] => Array
                (
                    [2] => Array
                        (
                            [0] => 123429000000010
                            [1] => 123429000000011
                        )

                    [3] => Array
                        (
                            [0] => 123429000000040
                            [1] => 123429000000041
                        )

                )

        )

)
10
  • 2
    Is it possible? - yes, so have a try yourself and add the code to your question. Commented Jan 28, 2020 at 19:04
  • 1
    Please don't just ask us to solve the problem for you. Show us how you tried to solve the problem yourself, then show us exactly what the result was, and tell us why you feel it didn't work. Give us a clear explanation of what isn't working and provide a Minimal, Complete, and Verifiable example. Read How to Ask a good question. Be sure to take the tour and read this. Commented Jan 28, 2020 at 19:05
  • 1
    You need to read line by line, put into an array with explode, count the index numbers then put into an array with your logic. Good luck. When you have a real code we can help you. Commented Jan 28, 2020 at 19:05
  • Is it possible for there to be multiple items in the same row, but those items have different starting 4 numbers? Commented Jan 28, 2020 at 19:16
  • yes @NigelRen I have edited my question. Commented Jan 28, 2020 at 19:17

1 Answer 1

1

This is based on reading the file as a csv (using fgetcsv()) and extracting the first 4 digits of the first value on each line. It then uses another array to give the key for the 'single_devices' etc. key - using the count of the number of elements on the line (-1 as the array is 0 based)...

$fileName = "a.dat";
$output = [];
$baseData = [ 'single_devices', 'dual_devices', 'triple_devices', 'quad_devices' ];
$fh = fopen ( $fileName, "r" );
while ( ($data = fgetcsv($fh)) !== false )  {
    $code = substr($data[0], 0, 4);
    $output[$code][$baseData[count($data)-1]][] = $data;
}

fclose($fh);

print_r($output);

which with the test data gives...

Array
(
    [1234] => Array
        (
            [single_devices] => Array
                (
                    [0] => Array
                        (
                            [0] => 123429000000000
                        )

                    [1] => Array
                        (
                            [0] => 123429000000001
                        )

                )

            [dual_devices] => Array
                (
                    [0] => Array
                        (
                            [0] => 123429000000010
                            [1] => 123429000000011
                        )

                    [1] => Array
                        (
                            [0] => 123429000000040
                            [1] => 123429000000041
                )

        )

)

With

while ( ($data = fgetcsv($fh)) !== false )  {
    $code = substr($data[0], 0, 4);
    if ( !isset($output[$code]))    {
        $output[$code] = ["code" => $code];
    }
    $deviceLabel = $baseData[count($data)-1];
    $output[$code][$deviceLabel]['count'] =
        ($output[$code][$deviceLabel]['count'] ?? 0) + 1;
    $output[$code][$deviceLabel][] = $data;
}

you can get an output of...

Array
(
    [1234] => Array
        (
            [code] => 1234
            [single_devices] => Array
                (
                    [count] => 2
                    [0] => Array
                        (
                            [0] => 123429000000000
                        )

                    [1] => Array
                        (
                            [0] => 123429000000001
                        )

                )
Sign up to request clarification or add additional context in comments.

9 Comments

That is correct. This is what I am currently getting with my code that I already have. But this isn't the desired array I am planning for.
If you mean you want [Code] => 1234 ( and [single_devices] => 2 (, that isn't a valid array format. You can add extra fields for them.
@Xia That's what I was getting at with my last comment. The result that you say you want isn't possible. That's why I was asking for you to show either a result that we can produce, or how you came up with what you're asking for.
@NigelRen Yes that is somewhat I was aiming for. Ok so it may not be valid array format but as I mentioned that is it possible to get such output in any other way?
@PatrickQ Yes I edited my answer and added the output I was getting.
|

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.