Spreading array values

Viewed 56

I have a multi dimensional array which I want to spread its data based on a shared scenario added below, I have tried a couple of way but it didn't return what I expect, I don't share my source code as it won't help and wasn't suitable to share.

Note: While generating the new sets of array year and order number of alphabet (A, B, C, D or ...) should be considered, .

This is my array:

array(
        array(["AF2021A"], ["AF2021B"], ["AF2020C"]), 
        array(["IR2022A","IR2021A"], ["IR2022B","IR2021B"], ["IR2022C","IR2021C"], ["IR2022D","IR2021D","IR2020D"]
        ));

I expect below results from this array:

First dimension should return this:

AF2020C - AF2021A 
AF2020C - AF2021B 
AF2021B - AF2021A

Second dimension should return this:

    IR2020D - IR2021A
    IR2020D - IR2021B
    IR2020D - IR2021C
    IR2020D - IR2021D
    IR2020D - IR2022A
    IR2020D - IR2022B
    IR2020D - IR2022C
    IR2020D - IR2022D

    IR2021A - IR2021B
    IR2021A - IR2021C
    IR2021A - IR2021D
    IR2021A - IR2022A
    IR2021A - IR2022B
    IR2021A - IR2022C
    IR2021A - IR2022D

    IR2021B - IR2021C
    IR2021B - IR2021D
    IR2021B - IR2022A
    IR2021B - IR2022B
    IR2021B - IR2022C
    IR2021B - IR2022D

    IR2021C - IR2021D
    IR2021C - IR2022A
    IR2021C - IR2022B
    IR2021C - IR2022C
    IR2021C - IR2022D

    IR2021D - IR2022A
    IR2021D - IR2022B
    IR2021D - IR2022C
    IR2021D - IR2022D

    IR2022A - IR2022B
    IR2022A - IR2022C
    IR2022A - IR2022D
    IR2022B - IR2022C
    IR2022B - IR2022D
    IR2022C - IR2022D
1 Answers

I'm going to slightly ignore your outer array, I think you can work to address that. The code below appears to have the same results as you show. I'm writing strings into another array, I'm not really sure what your true expected output is supposed to be either. Also, I'm outputting an empty item, solely to match your spacing, you can either remove it or apply logic as needed.

First, we need to clean, de-duplicate (just in case) and sort the array:

function cleanArray(array $array): array
{
    $clean = [];
    foreach ($array as $item) {
        array_push($clean, ...$item);
    }

    $clean = array_unique($clean);
    sort($clean);
    return $clean;
}

Then the main function walks the array, taking the first item out, loops over the remaining and appends, and repeats until there's only one thing left. The switch/case is up to you for any business logic for edge cases with missing or only one item.

function processArray(array $array): array
{
    $array = cleanArray($array);
    switch (count($array)) {
        case 0:
            // Edge case, not sure
            return [];
        case 1:
            // Edge case again, not sure
            return [];
        case 2:
            return [sprintf('%1%s - %2$s', $array[0], $array[1])];
        default:
            $ret = [];
            while (count($array) >= 2) {
                $currentItem = array_shift($array);
                foreach ($array as $item) {
                    $ret[] = sprintf('%1$s - %2$s', $currentItem, $item);
                }
                $ret[] = '';
            }

            return $ret;
    }
}

This could also be done with recursion, but sometimes, if you can avoid that, it is much easier.

This can be tested with:

print_r(processArray([["IR2022A", "IR2021A"], ["IR2022B", "IR2021B"], ["IR2022C", "IR2021C"], ["IR2022D", "IR2021D", "IR2020D"]]));
print_r(processArray([["AF2021A"], ["AF2021B"], ["AF2020C"]]));

The only thing that doesn't seem to match up is the third row in your first sample. I don't understand by B comes before A, is that a typo?

Related