PHP находит значения в Multi-Dimetional Array

Я ищу даты, которые соответствуют событиям, и надеюсь вернуть название события.
Вот простой пример использования Дней Рождения.

function find_event( $month,$day ){

$event = array(
["Sam","1","1"],
["Jim","2","3"],
["Sally","3","11"],
["Buck","4","4"],
["Ted","12","22"]
); // event name, month, day

/* what code goes here? */

return "Happy Birthday, ".$event[$key][0]."!";
}

find_event(12,22);

-1

Решение

Вы можете попробовать это:

<?php
function find_event( $month,$day ){

$event = array(
["Sam","1","1"],
["Jim","2","3"],
["Sally","3","11"],
["Buck","4","4"],
["Ted","12","22"]
); // event name, month, day

foreach ($event as $e) {
if($e[1] == $month && $e[2] == $day) {
return "Happy Birthday, ". $e[0]."!";
}
}
return null;
}

echo find_event(12,22);
1

Другие решения

Не проверено, но для этого нужно работать:

foreach ($event as $key => $e) {
if ($e[1] == $month && $e[2] == $day) {
$match = $key;
break;
}
}

if (!empty($match)) {
return $event[$match][0];
}
1

(пропустите до конца, чтобы пропустить объяснение и получить закомментированный код с «лучшим» долгосрочным решением)

Отказ от ответственности: Этот материал не является необходимым для небольшого проекта … Но в качестве учебного упражнения я рекомендую сделать это. Это создает гораздо более стабильный, гибкий, читаемый код в долгосрочной перспективе. Не говоря уже о том, что если вы устроитесь на работу программистом, вам нужно знать, как делать то, что сделано ниже.

Для этого вам следует рассмотреть возможность использования классов, а не числовых индексированных массивов. Другой альтернативой будет использование ассоциативных массивов.

Использование ассоциативных массивов:

function print_event($month, $day)
{
$events = [
[
"name" => "Sam",
"month" => "1",
"day" => "1"],
[
"name" => "Jim",
"month" => "2",
"day" => "3"],
[
"name" => "Sally",
"month" => "3",
"day" => "11"],
[
"name" => "Buck",
"month" => "4",
"day" => "4"],
[
"name" => "Ted",
"month" => "12",
"day" => "22"]
]; // It is now clear exactly what is going on here. No need to tell me with a comment.

foreach ($events as $event) {
if ($month === $event["month"] && $day === $event["day"])
return "Happy Birthday, ".$event["name"]."!";
}
return "No birthdays today";
}

Вышеописанный способ работает довольно хорошо, но это быстрое и грязное решение. Вы ДОЛЖНЫ использовать объекты:

function print_event($month, $day) {
$events = [
new BirthdayEvent("Sam", "1", "1"),
new BirthdayEvent("Jim", "2", "3"),
new BirthdayEvent("Sally", "3", "11"),
new BirthdayEvent("Buck", "4", "4"),
new BirthdayEvent("Ted", "12", "22")
]; //It is now clear exactly what is going on here. No need to tell me with a comment.

foreach ($events as $event) {
if ($event->isToday($month, $day)) {
return "Happy Birthday, " . $event->name . "!";
}
}
return "No birthdays today";
}

public class BirthdayEvent {
public function __construct($name, $month, $day){
$this->name = $name;
$this->month = $month;
$this->day = $day;
}

public function isToday($month, $day){
return $this->month === $month && $this->day === $day;
}
}

Это намного лучше, НО все еще может улучшиться! Прямо сейчас, событие print работает ТОЛЬКО для некоторых событий, которые вы ОБРАБОТАЛИ, и эти события восстанавливаются в памяти КАЖДЫЙ раз, когда вызывается эта функция! Какая катастрофа! Это можно быстро решить, просто определив эти события вне кода, а затем передав их в качестве параметра, например так:

$events = [
new BirthdayEvent("Sam", "1", "1"),
new BirthdayEvent("Jim", "2", "3"),
new BirthdayEvent("Sally", "3", "11"),
new BirthdayEvent("Buck", "4", "4"),
new BirthdayEvent("Ted", "12", "22")
]; //It is now clear exactly what is going on here. No need to tell me with a comment.

function print_event($events, $month, $day) {... rest of code ...}

Теперь это становится довольно хорошо … Но это можно сделать еще лучше! print_event на самом деле делает две вещи … это и печать события, и нахождение события. Мы должны сделать событие поиска своей собственной функцией.

Теперь наш блок кода выглядит так:

function print_event($events, $month, $day) {
$event = find_event($events, $month, $day);
if($event === null)
return "No birthdays today"; //No event was found. No birthday today
else
return "Happy birthday, ".$event->name."!"; //An event was found! Happy birthday!
}

function find_event($events, $month, $day) {
foreach ($events as $event) {
if ($event->isToday($month, $day)) {
return $event; //Yay we found an event! return it!
}
}
return null; // We didn't find anything.  return null
}

Это снова еще лучше! Если разбить его, код начинает читаться как английский! Мы продвинулись довольно далеко, но это все еще относительно негибко. Давайте исправим это …

// create our events
$events = [
new BirthdayEvent("Sam", "1", "1"),
new BirthdayEvent("Jim", "2", "3"),
new BirthdayEvent("Sally", "3", "11"),
new BirthdayEvent("Buck", "4", "4"),
new BirthdayEvent("Ted", "12", "22")
]; //It is now clear exactly what is going on here. No need to tell me with a comment.

//This function will print the greeting from the event
function print_event(array $events, $month, $day) {
$event = find_event($events, $month, $day);
if($event === null)
return "No events today"; //No event was found.
else
return $event->getGreeting(); //An event was found! Happy birthday!
}

//This function will find an event with a given month/day from an array of events
function find_event(array $events, $month, $day) {
foreach ($events as $event) {
if ($event->isToday($month, $day)) {
return $event; //Yay we found an event! return it!
}
}
return null; // We didn't find anything.  return null
}

// This interface says, "Anything that implements me MUST HAVE THESE METHODS!"interface EventInterface {
public function isToday($month, $day);
public function getGreeting();
}

// This class implements event by defining the methods in the Event interface
public class BirthdayEvent implements EventInterface{

protected $name;
protected $month;
protected $day;

public function __construct($name, $month, $day){
$this->name = $name;
$this->month = $month;
$this->day = $day;
}

// return true if the event is today
public function isToday($month, $day){
return $this->month === $month && $this->day === $day;
}

public function getGreeting(){
return "Happy birthday, ".$this->name."!";
}
}

//Finally, echo the output
echo print_event($events, "3", "11");

Мы добавили интерфейс. Этот интерфейс позволяет нам создавать различные типы событий, которые остаются совместимыми с функциями print_event и find_event! смотреть:

// This interface says, "Anything that implements me MUST HAVE THESE METHODS!"interface EventInterface {
public function isToday($month, $day);
public function getGreeting();
}

// This class implements event by defining the methods in the Event interface
public class BirthdayEvent implements EventInterface{

protected $name;
protected $month;
protected $day;

public function __construct($name, $month, $day){
$this->name = $name;
$this->month = $month;
$this->day = $day;
}

// return true if the event is today
public function isToday($month, $day){
return $this->month == $month && $this->day == $day;
}

public function getGreeting(){
return "Happy birthday, ".$this->name."!";
}
}

// This class implements event by defining the methods in the Event interface
public class HolidayEvent implements EventInterface{
protected $name;
protected $month;
protected $day;

public function __construct($name, $month, $day){
$this->name = $name;
$this->month = $month;
$this->day = $day;
}

// return true if the event is today
public function isToday($month, $day){
return $this->month === $month && $this->day === $day;
}

public function getGreeting(){
return "Happy ".$this->name."!"; //For example, it would print "Happy Columbus Day!" if it were columbus day
}
}

и теперь наш массив событий может выглядеть так:

// create our events
$events = [
new BirthdayEvent("Sam", "1", "1"),
new BirthdayEvent("Jim", "2", "3"),
new BirthdayEvent("Sally", "3", "11"),
new BirthdayEvent("Buck", "4", "4"),
new BirthdayEvent("Ted", "12", "22"),
new HolidayEvent("Columbus Day", "10", "13"),
new HolidayEvent("Labor Day", "9", "1")
]; //It is now clear exactly what is going on here. No need to tell me with a comment.

Теперь это здорово и все, но есть еще одна вещь, которую нужно сделать … между этими двумя классами событий есть довольно много дублирующего кода! Ниже мы представляем абстрактный класс, чтобы забыть о написании кода дважды!

//This is an abstract class. On it's own, it serves no purpose. But it can be extended to reduce duplicate code!
abstract class BaseEvent implements EventInterface {
protected $name;
protected $month;
protected $day;

public function __construct($name, $month, $day){
$this->name = $name;
$this->month = $month;
$this->day = $day;
}

// return true if the event is today
public function isToday($month, $day){
return $this->month == $month && $this->day == $day;
}
}

// This class implements event by defining the methods in the Event interface
public class BirthdayEvent extends BaseEvent {
public function getGreeting(){
return "Happy birthday, ".$this->name."!";
}
}

// This class implements event by defining the methods in the Event interface
public class HolidayEvent extends BaseEvent{
public function getGreeting() {
return "Happy ".$this->name."!"; //For example, it would print "Happy Columbus Day!" if it were columbus day
}
}

Это, вероятно, излишне для того, что вы пытаетесь сделать, но это лучший способ решить подобные проблемы в больших проектах с большой сложностью. Используя это, вы теперь можете создавать новые типы событий просто так:

public class SomeAwesomeNewTypeOfEvent extends BaseEvent {
public function getGreeting() {
return "Some awesome greeting goes here";
}
}

Вот как все будет выглядеть, когда все сказано и сделано:

// create our events
$events = [
new BirthdayEvent("Sam", "1", "1"),
new BirthdayEvent("Jim", "2", "3"),
new BirthdayEvent("Sally", "3", "11"),
new BirthdayEvent("Buck", "4", "4"),
new BirthdayEvent("Ted", "12", "22"),
new HolidayEvent("Columbus Day", "10", "13"),
new HolidayEvent("Labor Day", "9", "1")
]; //It is now clear exactly what is going on here. No need to tell me with a comment.

//This function will print the greeting from the event
function print_event(array $events, $month, $day) {
$event = find_event($events, $month, $day);
if($event === null)
return "No events today"; //No event was found.
else
return $event->getGreeting(); //An event was found! Happy birthday!
}

//This function will find an event with a given month/day from an array of events
function find_event(array $events, $month, $day) {
foreach ($events as $event) {
if ($event->isToday($month, $day)) {
return $event; //Yay we found an event! return it!
}
}
return null; // We didn't find anything.  return null
}

// This interface says, "Anything that implements me MUST HAVE THESE METHODS!"interface EventInterface {
public function isToday($month, $day);
public function getGreeting();
}

//This is an abstract class. On it's own, it serves no purpose. But it can be extended to reduce duplicate code!
abstract class BaseEvent implements EventInterface {
protected $name;
protected $month;
protected $day;

public function __construct($name, $month, $day){
$this->name = $name;
$this->month = $month;
$this->day = $day;
}

// return true if the event is today
public function isToday($month, $day){
return $this->month == $month && $this->day == $day;
}
}

// This class implements event by defining the methods in the Event interface
public class BirthdayEvent extends BaseEvent {
public function getGreeting(){
return "Happy birthday, ".$this->name."!";
}
}

// This class implements event by defining the methods in the Event interface
public class HolidayEvent extends BaseEvent{
public function getGreeting(){
return "Happy ".$this->name."!"; //For example, it would print "Happy Columbus Day!" if it were columbus day
}
}

//Finally, echo the output
echo print_event($events, "3", "11");

Дайте мне знать, если вы хотите, чтобы я что-то объяснил.

0