Ered
Ered

Reputation: 497

php loop show current year data if not found instead of skiping

So I have a loop within a loop both have year data and I'm trying to figure out how to show current year (2021) data if years don't match or exist on loop instead of using continue to skip the entry, any ideas or solutions are appreciated.

LIVE CODE: http://sandbox.onlinephpfunctions.com/code/b7cbef0613636aa41a41a7d5f283a2569ece9cb0

$dates = [
    ['date_starts'=>'2021-03-22'],
    ['date_starts'=>'2022-04-22'],
    ['date_starts'=>'2023-05-22']
];
              
foreach( $dates as $dt ){
    $start_date = $dt['date_starts'];
    
    $rates_results = [
        ['price'=>255,'year'=>'2021'],
        ['price'=>300,'year'=>'2023']
    ];

    $rateIDs = [];
    if ($rates_results) {
        foreach ($rates_results as $rates) {
            if(date("Y", strtotime($start_date)) !== ''.$rates['year'].''){
                continue;
            }
            
            $rateIDs [] = [
                'year' => $rates['year'],
                'price' => $rates['price']
            ];
        }
    }
    print_r($rateIDs);
}

So this is the OUTPUT I get:

Array
(
    [0] => Array
        (
            [year] => 2021
            [price] => 255
        )

)
Array
(
)
Array
(
    [0] => Array
        (
            [year] => 2023
            [price] => 300
        )

)

And this is the result I'm looking for:

Array
(
    [0] => Array
        (
            [year] => 2021
            [price] => 255
        )

)
Array
(
    [0] => Array
        (
            [year] => 2021
            [price] => 255
        )

)
Array
(
    [0] => Array
        (
            [year] => 2023
            [price] => 300
        )

)

Upvotes: 1

Views: 158

Answers (4)

Nick
Nick

Reputation: 147206

Judging from the answers and the comments to them, it seems perhaps you are looking for something like this:

$dates = [
    ['date_starts'=>'2021-03-22'],
    ['date_starts'=>'2022-04-22'],
    ['date_starts'=>'2023-05-22']
];

$current_year = date('Y');
              
foreach ($dates as $dt) {
    
    $rates_results = [
        ['price'=>255, 'year'=>'2021'],
        ['price'=>200, 'year'=>'2021'],
        ['price'=>300, 'year'=>'2023']
    ];
    
    // get the year from the start date. Since it's in YYYY-MM-DD format
    // we can just use substr
    $start_year = substr($dt['date_starts'], 0, 4);
    
    // find matching years in $rates_results
    $rate_keys = array_keys(array_column($rates_results, 'year'), $start_year);
    
    // any matches?
    if (empty($rate_keys)) {
        // no, use the values from the current year instead
        $rate_keys = array_keys(array_column($rates_results, 'year'), $current_year);
    }
    
    // get the actual rates
    $code = 1;
    $rates = array();
    foreach ($rate_keys as $key) {
        $rates[] = [
            'custom' => $code,
            'price' => $rates_results[$key]['price'],
            'year' => $rates_results[$key]['year']
            ];
    }
    
    // output the rates
    print_r($rates);
}

Output:

Array
(
    [0] => Array
        (
            [price] => 255
            [year] => 2021
        )

    [1] => Array
        (
            [price] => 200
            [year] => 2021
        )

)
Array
(
    [0] => Array
        (
            [price] => 255
            [year] => 2021
        )

    [1] => Array
        (
            [price] => 200
            [year] => 2021
        )

)
Array
(
    [0] => Array
        (
            [price] => 300
            [year] => 2023
        )

)

Demo on 3v4l.org

Upvotes: 1

Steven
Steven

Reputation: 6148

I think you're overcomplicating this having nested for loops. In reality you have a dates array and a rates array and you want to cross reference one against the other?

To do this what you need to do is loop through the dates array and then use PHPs array_* functions to find the key for the specific year; then if the nothing was found then use the current year.

$dates = [
    ['date_starts'=>'2021-03-22'],
    ['date_starts'=>'2022-04-22'],
    ['date_starts'=>'2023-05-22']
];

$rates_results = [
    ['price'=>255,'year'=>'2021'],
    ['price'=>300,'year'=>'2023']
];
$rate_year_array = array_column($rates_results, "year");             // Extract year "column" from $rates_results


foreach ($dates as $date_row) {
    $search_year  = date("Y", strtotime($date_row["date_starts"]));  // Get the year to look up from the date supplied
    $rate_key     = array_search($search_year, $rate_year_array);    // Search the "year" array and get the key for the current year
                                                                     // If not found then the value will be (bool) false
    
    if ($rate_key === false) {                                       // Check if the key was found
        $rate_key = array_search(date("Y"), $rate_year_array);       // If not find the key for the current year
    }

    // Output the date to an array
    $rateIDs[] = [
        'year'  => $rates_results[$rate_key]["year"],
        'price' => $rates_results[$rate_key]["price"],
    ];

}

print_r($rateIDs);  // Print the array

Output:

Array
(
    [0] => Array
        (
            [year] => 2021
            [price] => 255
        )

    [1] => Array
        (
            [year] => 2021
            [price] => 255
        )

    [2] => Array
        (
            [year] => 2023
            [price] => 300
        )

)

Upvotes: 3

ev0tix
ev0tix

Reputation: 17

I'm not sure I understood correctly, but here goes...

Initialize a $matched variable before the loop, and set it to true if there is a match (to know there's no need to add current year data).

If there was no match, search the data array ($rates_results) to see if the current year exists, if so, add it to the result

<?php
$dates = [
    ['date_starts'=>'2021-03-22'],
    ['date_starts'=>'2022-04-22'],
    ['date_starts'=>'2023-05-22']
];
              
foreach( $dates as $dt ){
    $start_date = $dt['date_starts'];
    
    $rates_results = [
        ['price'=>255,'year'=>'2021'],
        ['price'=>300,'year'=>'2023']
    ];

    $rateIDs = [];
    if ($rates_results) {
        $matched = false;
        
        foreach ($rates_results as $rates) {
            if(date("Y", strtotime($start_date)) !== ''.$rates['year'].'') {
                continue;
            }
            
            $matched = true;
            $rateIDs[] = [
                'year' => $rates['year'],
                'price' => $rates['price']
            ];
        }
        
        if ($matched === false) {
            $key = array_search(date('Y'), array_column($rates_results, 'year'));
            if ($key !== false) {
                $rateIDs[] = [
                    'year' => $rates_results[$key]['year'],
                    'price' => $rates_results[$key]['price']
                ];
            }
        }
    }
    print_r($rateIDs);
}

Upvotes: 1

Basharmal
Basharmal

Reputation: 1384

Try this

    $dates = [
    ['date_starts'=>'2021-03-22'],
    ['date_starts'=>'2022-04-22'],
    ['date_starts'=>'2023-05-22']
];
              
foreach( $dates as $dt ){
    $start_date = $dt['date_starts'];
    
    $rates_results = [
        ['price'=>255,'year'=>'2021'],
        ['price'=>300,'year'=>'2022'],
        ['price'=>300,'year'=>'2023']
    ];

    $rateIDs = [];
    if ($rates_results) {
        foreach ($rates_results as $rates) {
            if(date("Y", strtotime($start_date)) !== ''.$rates['year'].''){
             
                continue;
                
            }
           
                $rateIDs [] = [
                'year' => $rates['year'],
                'price' => $rates['price']
            ];
            
            
           
        }
    }
    print_r($rateIDs);
}

Upvotes: 0

Related Questions