skip to Main Content

I am building a collection from a Facebook API response.

$ads = new IlluminateSupportCollection;

if (!$ads->has($insight[$key])) {
    $ads->put($insight[$key], [
        'ad_id'                             => $insight[AdsInsightsFields::AD_ID],
        'ad_name'                           => $insight[AdsInsightsFields::AD_NAME],
        'ctr'                               => (float)$insight[AdsInsightsFields::CTR],
        'spend'                             => (float)$insight[AdsInsightsFields::SPEND],
    ]);
} else {
    // Increment spend value here.
}

If this were an array, I’d just do this:

$ads[$insight[$key]]['spend'] += $insight[AdsInsightsFields::SPEND];

How do I do that on a Collection?

3

Answers


  1. Chosen as BEST ANSWER

    To solve this I wrote macros capable of performing the updates needed.

    // Set a single value by dot notation key.
    Collection::macro('set', function ($key, $new) {
        $key = explode('.', $key);
        $primary_key = array_shift($key);
        $key = implode('.', $key);
        $current = $this->get($primary_key);
    
        if (!empty($key) && is_array($current)) {
            array_set($current, $key, $new);
        } else {
            $current = $new;
        }
    
        $this->put($primary_key, $current);
    });
    // Increment a single value by dot notation key.
    Collection::macro('increment', function ($key, $amount) {
        $key = explode('.', $key);
        $primary_key = array_shift($key);
        $key = implode('.', $key);
        $current = $this->get($primary_key);
    
        if (!empty($key) && is_array($current)) {
            $new = array_get($current, $key, 0);
            $new += $amount;
    
            array_set($current, $key, $new);
        } else {
            $current += $amount;
        }
    
        $this->put($primary_key, $current);
    });
    // Decrement a single value by dot notation key.
    Collection::macro('decrement', function ($key, $amount) {
        $key = explode('.', $key);
        $primary_key = array_shift($key);
        $key = implode('.', $key);
        $current = $this->get($primary_key);
    
        if (!empty($key) && is_array($current)) {
            $new = array_get($current, $key, 0);
            $new -= $amount;
    
            array_set($current, $key, $new);
        } else {
            $current -= $amount;
        }
    
        $this->put($primary_key, $current);
    });
    

    With this, all I need to do is something like:

    $ads->increment($insight[$key] . '.spend', $insight[AdsInsightsFields::SPEND]);
    

    If I want to simply set a value, whether the key exists or not, I can do this:

    $ads->set($insight[$key] . '.spend', $insight[AdsInsightsFields::SPEND]);
    

  2. $ads->{$insight[$key]}['spend'] +=  $insight[AdsInsightsFields::SPEND];
    

    It’s a little weird looking but you need to access the first part as an object property ->propertyName, that property name you’re grabbing from an array $insight[$key] so you need to throw brackets around it, finally you need to ask for an array key of that property with [spend] at the end.

    Login or Signup to reply.
  3. first thing, this is a collection of arrays (not a collection of collection).

    your question was how to get a particular key value pair in a collection,

    The Answer is ‘get()’ function on collection.
    now you can simply increment the ‘spend’ value as below.

    $ads->get($insight[$key])['spend'] += $insight[AdsInsightsFields::SPEND];
    

    NOTE

    if you need whole thing to be collections, Update your code to make a collection of collection as below

    $ads->put($insight[$key],  collection([
        'add_id'                            => $insight[AdsInsightsFields::AD_ID],
        'ad_name'                           => $insight[AdsInsightsFields::AD_NAME],
        'ctr'                               => (float)$insight[AdsInsightsFields::CTR],
        'spend'                             => (float)$insight[AdsInsightsFields::SPEND],
    ]);
    

    then you can increment spend value as below.

    $ads->get($insight[$key])->spend += $insight[AdsInsightsFields::SPEND];
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search