更新 Laravel Illuminate collection 中的单个键值

Update a single key value in a Laravel Illuminate collection

我正在从 Facebook API 响应构建 collection。

$ads = new \Illuminate\Support\Collection;

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.
}

如果这是一个数组,我会这样做:

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

如何在 Collection 上执行此操作?

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

它看起来有点奇怪,但您需要将第一部分作为对象访问 属性 ->propertyName,您从数组中获取的 属性 名称 $insight[$key] 所以你需要在它周围加上方括号,最后你需要在末尾请求 属性 和 [spend] 的数组键。

首先,这是数组的集合(不是集合的集合)。

您的问题是如何获取集合中的特定键值对,

答案是'get()'集合函数。 现在您可以简单地增加 'spend' 值,如下所示。

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

注意

如果你需要整个东西成为集合,更新你的代码来制作一个集合集合如下

$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],
]);

然后您可以如下增加支出价值。

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

为了解决这个问题,我编写了能够执行所需更新的宏。

// 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);
});

有了这个,我需要做的就是:

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

如果我想简单的设置一个值,key是否存在,我可以这样做:

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