首页 > 解决方案 > 用例的对象或数组

问题描述

我是 PHP 新手,不确定是否应该在用例中使用数组或对象。

// 名称
// 身高
// 体重
// 头发颜色

可能的阵列解决方案:

<?php
$Alex = array("Alex" "190","90","blond");
$Jim = array("Jim" "160","90","brown");
$Sarah = array("Sarah" "175","50","blond");
$Kevin = array("Kevin" "160","50","brown");
?>

$merged_arrays = array_merge( $Alex, $Jim, $Sarah, $Kevin);

稍后用户应该能够选择所有 3 个值(或仅选择 1 个)。

示例 1:用户选择:身高“160”和头发颜色“棕色”-> 输出应为“Jim”和“Kevin”

示例 2:用户选择:权重“50”-> 输出“Sarah”和“Kevin”

我不确定在这里使用数组是否明智,或者我应该切换到对象,因为所有人都会有相同的值(姓名、身高、体重和头发颜色)。

IF 数组可以很好地解决这个问题,我不确定如何搜索和输出上面提到的选定值。

我找到了这个,但这并没有真正的帮助Search Multiple Arrays for

此致

标签: phparraysobject

解决方案


我将用 2 种可能的解决方案(foreach、array_filter)为您的示例 1 介绍数组和对象。

第一个数组。对于结构化数据,您希望使用关联数组,以便您的人员拥有有意义的键。比较一下:

$p = ["Alex", "190","90","blond"];
echo $p[2];

与这个:

$p = ['name' => "Alex", 'height' => "190", 'weight' => "90",'hair' => "blond";
echo $p['weight'];

哪一个更容易理解?

还要为您的数据使用正确的类型。高度和重量可以是整数(或浮点数) - 并非所有内容都必须是字符串。

关联数组解决方案。

创建您的数据 ($people) 和您的过滤条件 ($criteria)。$criteria 可以是动态的,您可以在那里添加或删除键

<?php

$alex = ['name' => 'Alex', 'height' => 190, 'weight' => 90, 'hair' => 'blond'];
$jim = ['name' => 'Jim', 'height' => 160, 'weight' => 90, 'hair' => 'brown'];
$sarah = ['name' => 'Sarah', 'height' => 175, 'weight' => 50, 'hair' => 'blond'];
$kevin = ['name' => 'Kevin', 'height' => 160, 'weight' => 50, 'hair' => 'brown'];

$people = [$alex, $jim, $sarah, $kevin];

var_dump($people);

$criteria = [ 
  'height' => 160,
  'hair' => 'brown',
];

// 1. search with foreach
$filteredPeople = [];
foreach ($people as $person) {
  $match = true;
  foreach ($criteria as $key => $value) {
    if ($person[$key] !== $value) {
      $match = false;
    }
  }

  if ($match) {
    $filteredPeople[] = $person;
  }
}

var_dump($filteredPeople);

// 2. use array_filter
$filteredPeople = array_filter($people, function (array $person) use ($criteria) {
  $match = true;
  foreach ($criteria as $key => $value) {
    if ($person[$key] !== $value) {
      $match = false;
    }
  }

  return $match;
});

var_dump($filteredPeople);

输出:

array(4) {
  [0]=>
  array(4) {
    ["name"]=>
    string(4) "Alex"
    ["height"]=>
    int(190)
    ["weight"]=>
    int(90)
    ["hair"]=>
    string(5) "blond"
  }
  [1]=>
  array(4) {
    ["name"]=>
    string(3) "Jim"
    ["height"]=>
    int(160)
    ["weight"]=>
    int(90)
    ["hair"]=>
    string(5) "brown"
  }
  [2]=>
  array(4) {
    ["name"]=>
    string(5) "Sarah"
    ["height"]=>
    int(175)
    ["weight"]=>
    int(50)
    ["hair"]=>
    string(5) "blond"
  }
  [3]=>
  array(4) {
    ["name"]=>
    string(5) "Kevin"
    ["height"]=>
    int(160)
    ["weight"]=>
    int(50)
    ["hair"]=>
    string(5) "brown"
  }
}
array(2) {
  [0]=>
  array(4) {
    ["name"]=>
    string(3) "Jim"
    ["height"]=>
    int(160)
    ["weight"]=>
    int(90)
    ["hair"]=>
    string(5) "brown"
  }
  [1]=>
  array(4) {
    ["name"]=>
    string(5) "Kevin"
    ["height"]=>
    int(160)
    ["weight"]=>
    int(50)
    ["hair"]=>
    string(5) "brown"
  }
}
array(2) {
  [1]=>
  array(4) {
    ["name"]=>
    string(3) "Jim"
    ["height"]=>
    int(160)
    ["weight"]=>
    int(90)
    ["hair"]=>
    string(5) "brown"
  }
  [3]=>
  array(4) {
    ["name"]=>
    string(5) "Kevin"
    ["height"]=>
    int(160)
    ["weight"]=>
    int(50)
    ["hair"]=>
    string(5) "brown"
  }
}

这有效,过滤数据,您可以动态指定标准(0,1,2,3,4 标准)。

对象解决方案。

现在对象。我的意见是 - 如果您有数据结构,请使用对象。他们定义结构,给你类型提示,方法。你有地方添加逻辑,验证。想用名字键(错字)添加人吗?不可能。意外修改/覆盖某些数据?不可能。想要验证高度不能超过 300?将其添加到构造函数中 - 在一个地方等。此外,您的 IDE 可以为您提供更多帮助,因为它还可以理解您使用的数据。

代码稍微复杂一些(例如,将标准映射到 getter 方法):

<?php

class Person {
  private $name;
  private $height;
  private $weight;
  private $hair;

  public function __construct(string $name, int $height, int $weight, string $hair) {
    $this->name = $name;
    $this->height = $height;
    $this->weight = $weight;
    $this->hair = $hair;
  }

  public function getName(): string {
    return $this->name;
  }

  public function getHeight(): int {
    return $this->height;
  }

  public function getWeight(): int {
    return $this->weight;
  }

  public function getHair(): string {
    return $this->hair;
  }
}

$alex = new Person('Alex', 190, 90, 'blond');
$jim = new Person('Jim', 160, 90, 'brown');
$sarah = new Person('Sarah', 175, 50, 'blond');
$kevin = new Person('Kevin', 160, 50, 'brown');

$people = [$alex, $jim, $sarah, $kevin];

var_dump($people);

$criteria = [ 
  'height' => 160,
  'hair' => 'brown',
];

// 1. search with foreach
$filteredPeople = [];
foreach ($people as $person) {
  $match = true;
  foreach ($criteria as $key => $value) {
    switch ($key) {
      case 'name':
        $data = $person->getName();
        break;
      case 'height':
        $data = $person->getHeight();
        break;
      case 'weight':
        $data = $person->getWeight();
        break;
      case 'hair':
        $data = $person->getHair();
        break;
      default:
        throw new Exception('Unknown criteria: '.$key);
    }

    if ($data !== $value) {
      $match = false;
    }
  }

  if ($match) {
    $filteredPeople[] = $person;
  }
}

var_dump($filteredPeople);

// 2. use array_filter
$filteredPeople = array_filter($people, function (Person $person) use ($criteria) {
  $match = true;
  foreach ($criteria as $key => $value) {
    switch ($key) {
      case 'name':
        $data = $person->getName();
        break;
      case 'height':
        $data = $person->getHeight();
        break;
      case 'weight':
        $data = $person->getWeight();
        break;
      case 'hair':
        $data = $person->getHair();
        break;
      default:
        throw new Exception('Unknown criteria: '.$key);
    }

    if ($data !== $value) {
      $match = false;
    }
  }

  return $match;
});

var_dump($filteredPeople);

输出:

array(4) {
  [0]=>
  object(Person)#1 (4) {
    ["name":"Person":private]=>
    string(4) "Alex"
    ["height":"Person":private]=>
    int(190)
    ["weight":"Person":private]=>
    int(90)
    ["hair":"Person":private]=>
    string(5) "blond"
  }
  [1]=>
  object(Person)#2 (4) {
    ["name":"Person":private]=>
    string(3) "Jim"
    ["height":"Person":private]=>
    int(160)
    ["weight":"Person":private]=>
    int(90)
    ["hair":"Person":private]=>
    string(5) "brown"
  }
  [2]=>
  object(Person)#3 (4) {
    ["name":"Person":private]=>
    string(5) "Sarah"
    ["height":"Person":private]=>
    int(175)
    ["weight":"Person":private]=>
    int(50)
    ["hair":"Person":private]=>
    string(5) "blond"
  }
  [3]=>
  object(Person)#4 (4) {
    ["name":"Person":private]=>
    string(5) "Kevin"
    ["height":"Person":private]=>
    int(160)
    ["weight":"Person":private]=>
    int(50)
    ["hair":"Person":private]=>
    string(5) "brown"
  }
}
array(2) {
  [0]=>
  object(Person)#2 (4) {
    ["name":"Person":private]=>
    string(3) "Jim"
    ["height":"Person":private]=>
    int(160)
    ["weight":"Person":private]=>
    int(90)
    ["hair":"Person":private]=>
    string(5) "brown"
  }
  [1]=>
  object(Person)#4 (4) {
    ["name":"Person":private]=>
    string(5) "Kevin"
    ["height":"Person":private]=>
    int(160)
    ["weight":"Person":private]=>
    int(50)
    ["hair":"Person":private]=>
    string(5) "brown"
  }
}
array(2) {
  [1]=>
  object(Person)#2 (4) {
    ["name":"Person":private]=>
    string(3) "Jim"
    ["height":"Person":private]=>
    int(160)
    ["weight":"Person":private]=>
    int(90)
    ["hair":"Person":private]=>
    string(5) "brown"
  }
  [3]=>
  object(Person)#4 (4) {
    ["name":"Person":private]=>
    string(5) "Kevin"
    ["height":"Person":private]=>
    int(160)
    ["weight":"Person":private]=>
    int(50)
    ["hair":"Person":private]=>
    string(5) "brown"
  }
}

人员数组、条件数组和过滤器代码也可以是此解决方案中的对象,但我觉得它超出了这个问题的范围。


推荐阅读