我如何从laravel雄辩的对象获得最高的属性

时间:2019-02-16 02:02:46

标签: laravel collections laravel-5.7

考虑以下模型对象:

App\Modules\CharacterSheets\Models\CharacterSheet {#826
  ...
  #attributes: array:39 [
    "id" => 1
    "user_id" => 1
    "race_id" => 1
    "class_id" => null
    "strength" => 35
    "dexterity" => 35
    "agility" => 55
    "intelligence" => 30
    "health" => 120
    "haste" => 0
    "precision" => 0
    "dodge" => 0
    "crit" => 0
    "steal_health" => 5
    "gold" => 0
    "deffense" => 7
    "damage" => 10
    "cast_damage" => 10
    "antique_damage" => 0
    "heal_for" => 10
    "level" => 1
    "train_exp" => 0
    "level_exp" => 200
    "location" => "0, 0"
    "next_level_exp" => 1000
    "next_train_level_exp" => 300
    "max_level" => 500
    "armor_class" => 17
    "block_bonus" => 3
    "hit_bonus" => 2
    "has_to_train" => 0
    "primary_attack_stat" => "health"
    "primary_attack_bonus" => "2.00"
    "penalty_stat" => null
    "penalty" => null
    "damage_subtraction" => null
    "chance_to_attack_twice" => null
    "created_at" => "2019-02-16 01:26:04"
    "updated_at" => "2019-02-16 01:56:42"
  ]
  ...
}

我想动态要做的是检查以下哪个统计值最高:strengthdexterityagility,{{ 1}},intelligence

我想保持对象不变,但将属性名称作为字符串返回

例如,对于上述对象,我应该具有返回health的函数。

同样,它必须是动态的

我没有看到任何laravel收集方法可以做到这一点,所以我在这里问,因为我不知道该怎么做。

3 个答案:

答案 0 :(得分:1)

从模型中提取属性并找到最大值键。

function getHighestProperty(Model $model, array $keys): string
{
    $filter = array_flip($keys);
    $array = collect($model->toArray());
    return $array->intersectByKeys($filter)->sort()->flip()->last();
}

答案 1 :(得分:0)

尽管我没有尝试过,但我会这样做:

首先,我们将创建所需的属性数组。

$array = [
    'strength', 'dexterity', 'agility', 'intelligence', 'health',
];

接下来,创建一个结果集合以存储上述$array中可用的图纸数据。

$result = collect();

环绕工作表并检查键是否在上述数组中。如果存在,我们将其放入$result集合中。

foreach ($characterSheet as $key => $sheetAttribute) {
    if (in_array($key, $array)) {
        $result->put($key, $sheetAttribute);
    }
}

然后,我们可以使用sort方法对$result集合进行排序,以为我们提供最小值及其键。然后,您可以flip,以获取与该值相关联的密钥,并返回last元素,因为您需要最大的密钥。

$result->sort()->flip()->last();

然后您可以简单地dd($result)并交叉验证这是否是您想要的。

答案 2 :(得分:0)

首先,弄清楚逻辑。在这种情况下,我们将使用Laravel Collections

// CharacterSheet.php

public function highestProperty()
{
    // temporal variable
    $temp = collect();

    // populating the temporal variable
    collect(['strength', 'dexterity', 'agility', 'intelligence', 'health'])
        ->each(function ($property) use ($temp) {
            return $temp->put($property, $this->$property);
        });

    // searching the property of the highest value
    return $temp->search(
        // getting the highest value
        $temp->reduce(function ($highest, $value) {
            return ($highest < $value) ? $value : $highest;
        })
    );
}

然后,创建一个accessor,因此您可以执行$characterSheet->highest_property

// CharacterSheet.php

public function getHighestPropertyAttribute()
{
    return $this->highestProperty();
}

您甚至可以append将此值添加到每个CharacterSheet实例中,并将其添加到$appends模型配置中:

// CharacterSheet.php

$appends = ['highest_property'];

现在,只要您获得CharacterSheet的实例,就可以像使用其他任何属性一样使用它:

$characterSheet = CharacterSheet::first();

dd($characterSheet->highest_property);

// this could output, if the case: "dexterity"