Реализация фильтра вложенных массивов в PHP / Wordpress - PullRequest
0 голосов
/ 19 февраля 2020

У меня есть процесс перемещения некоторого кода из внешнего интерфейса (в JavaScript) на серверную часть (то есть PHP), где он будет отфильтрован и отправлен в вызове API, и я не могу заставить фильтр работать должным образом на сервере. Код берет массив объектов и фильтрует его для объектов, где определенное вложенное поле (которое также является массивом объектов) содержит определенные значения. Базовая c форма API:

{
  "id": 1217,
  "name": "Best product ever",
  "tags": [
      {
        "id": 125,
        "name": "Important Value",
        "slug": "important-value"
      },
      {
        "id": 157,
        "name": "Value",
        "slug": "value"
      },
      {
    "id": 180,
    "name": "Value",
    "slug": "value"
  },
  {
    "id": 126,
    "name": "Value",
    "slug": "value"
  },
  {
    "id": 206,
    "name": "Other Important Value",
    "slug": "other-important-value"
  }
}

Рабочий JS код:

let productAttributes = ['important-value', 'value', 'value', 'value', 'other-important-value'];

filterResults(results) {
let filteredResults = results.filter(product => {
  return product.tags.find(tag => {
    return tag.slug === this.productAttributes[0];
  });
});

if (this.productAttributes[0] !== 'certain important value') {
  filteredResults = filteredResults.filter(product => {
    return product.tags.find(tag => {
      return tag.slug === this.productAttributes[4];
    });
  });
}

return filteredResults;
}

И (еще не работающий) PHP код:

function get_awesome_products() {
 $baseRequest = 'https://myawesomeapi/wp-json/wc/v3/products/? 
 consumer_key=xxxx&consumer_secret=xxxx&per_page=100&page=';
 for ($count = 1; $count <= 9; $count++ ) {
$request = wp_remote_get( $baseRequest . (string)$count);
$body = wp_remote_retrieve_body( $request );
$data = array_values( json_decode( $body, true ));

  if ($count < 2) {
    $completeProductList = $data;
  } else {
    $completeProductList = array_merge($completeProductList, $data);
  }
}
// The code above this comment is doing what I expect, the code below is not.


$filteredProducts = null;
foreach ($completeProductList as &$product) {
  $tagArray = $product['tags'];
  if (in_array($reg_test_array[0], $tagArray, true) && 
  in_array($reg_test_array[4], $tagArray, true)) 
  {
    array_push($filteredProducts, $product);
  }

  unset($product);
  return new WP_REST_Response($filteredProducts, 200);

Создается впечатление, что мне нужно написать пользовательскую функцию, чтобы заменить Array.prototype.find(), но я не силен в PHP и у меня возникают проблемы, когда я оборачиваюсь вокруг нее.

EDIT: отредактировано, чтобы добавить пример фильтруемого объекта и дополнительный PHP код

Ответы [ 2 ]

1 голос
/ 19 февраля 2020

Вы также можете использовать для этой задачи PHP эквивалентную функцию array_filter (среди нескольких других функций, определяющих массив c).

Пример:

// Your 0 and 4 index values from $reg_test_array
$importantTags = [ "important-value", "other-important-value" ];

$filteredProducts = array_filter($completeProductList, function($product) use ($importantTags) {
  return (bool)array_intersect($importantTags, array_column($product['tags'], 'slug'));
});

return new WP_REST_Response($filteredProducts , 200);

Песочница

1 голос
/ 19 февраля 2020

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

Не зная контекста important-value и other-important-value и того, как они поступают При заказе в массиве $attributes немного сложнее улучшить используемые условные проверки. Однако то, что я написал до сих пор, кажется мне запахом кода, потому что это зависит от жестко закодированных значений.

function filterResults(array $results, array $attributes)
{
    return array_reduce($results, function ($filteredResults, $result) use ($attributes) {
        // Extract tag slugs from result
        $tagSlugs = array_column($result['tags'], 'slug');

        // Append result to filtered results where first attribute exists in tag slugs; 
        // Or first attribute is not *other-important-value* and fourth attribute exists in tag slugs
        if (in_array($attribute[0], $tagSlugs) && ($attribute[0] === 'other-important-value' || in_array($attribute[4], $tagSlugs))) {
            $filteredResults[] = $result;
        }

        return $filteredResults;
    }, []);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...