Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

symphony28's avatar

Iterate over two collections

Hello, i am trying to get the result from a command, and in this result i need to pass properties from two different collection from my DB. what can i pass in that foreach loop to get the results?

	$stock = Stock::whereSymbol($this->argument('stock'))->first();
    $dailyClosePrices = DailyClosePrice::where('stock_id', $stock->id)
        ->selectRaw('date(date) as date')
        ->selectRaw('close_price as price')
        ->orderBy('date')
        ->get();

    $dividends = Dividend::where('stock_id', $stock->id)
        ->selectRaw('ex_date as date')
        ->selectRaw('dividend as dividend')
        ->orderBy('date')
        ->get();

    $dividendYield = DividendYield::where('stock_id', $stock->id)->first();
    if (!$dividendYield) {
        foreach( ... ) {
            resolve(CreateDividendYieldAction::class)->create(new DividendyieldData(
                stock: $stock,
                date: $dailyClosePrices->date,
                yield: $dividends->divident / $dailyClosePrices->price * 100,
                price: $dailyClosePrices->price,
                yearlyDividend: $dividends->dividend
            ));
        }
        
    }
0 likes
4 replies
tykus's avatar

Does this require a nested loop? Say there are 10 items in $dailyClosePrices and 5 items in $dividends; then should you have 50 DividendyieldData instances after looping?

symphony28's avatar

@tykus Yes, the $dailyClosePrices is bigger then $dividends, let's say your example that $dailyClosePrices contains 10 items int from 1-10 and $dividends contains 5 items in form 1-5. I need that first two items from $dailyClosePrices to divided first element of $dividends, then the next two with the second element. So in the end as many elements has $dailyClosePrices so the results contains the same number of items. What i mean :$res1= 1/1, $res2= 1/2, $res3= 2/3, $res4 = 2/4, $res5=3/5, $res6= 3/6, $res7=4/7, $res8=4/8, $res9=5/9, $res10=5/10

tykus's avatar

@stephan14 okay; will it alway align so perfectly (i.e. one $dividends item can be matched to exactly two $dailyClosePrices? This is what I am thinking for now:

if (!$dividendYield) {
    foreach($dividends as $i => $dividend) {
        foreach($dailyClosePrices->skip(2*$i)->take(2) as $dailyClosePrice) {
            resolve(CreateDividendYieldAction::class)->create(new DividendyieldData(
                stock: $stock,
                date: $dailyClosePrice->date,
                yield: $dividend->divident / $dailyClosePrice->price * 100,
                price: $dailyClosePrice->price,
                yearlyDividend: $dividend->dividend
            ));
        }
    }
}

Notice that we are iterating over the smaller Collection and skip-taking from the larger Collection based on the current index. Last, inside the nested loop, we are working with the individual instances $dividend and $dailyClosePrice, not the Collections

symphony28's avatar

@tykus No, that's the thing... will not always match perfect 2 items, thank you for your time anyway

Please or to participate in this conversation.