0
votes

Boucle un tableau et ne conserve que les éléments liés à une clé spécifique avec une valeur qualifiante

J'ai ce tableau:

[floorplans_1_valid_for_export] => 1
[floorplans_1_title] => title xx
[floorplans_1_house_area] => 90m²
[floorplans_1_bedrooms] => 2
[floorplans_2_valid_for_export] => 1
[floorplans_2_title] => title 2
[floorplans_2_house_area] => 50m²
[floorplans_2_bedrooms] => 1

Comme nous pouvons le voir dans les données, nous avons des champs ( floorplans_X_valid_for_export ). Ce que je veux faire, c'est obtenir les données uniquement lorsque ce champ est égal à 1 .

Donc à partir de l'exemple donné, je souhaite ne conserver que ces champs:

(
  [id] => block_5df755210d30a
  [name] => acf/floorplans
  [data] => Array
  (
    [floorplans_0_valid_for_export] => 0
    [floorplans_0_title] => title 1
    [floorplans_0_house_area] => 40m²
    [floorplans_0_bedrooms] => 1
    [floorplans_1_valid_for_export] => 1
    [floorplans_1_title] => title xx
    [floorplans_1_house_area] => 90m²
    [floorplans_1_bedrooms] => 2
    [floorplans_2_valid_for_export] => 1
    [floorplans_2_title] => title 2
    [floorplans_2_house_area] => 50m²
    [floorplans_2_bedrooms] => 1
    [floorplans] => 3

  )
)


2 commentaires

dans floorplans_X_valid_for_export X est-il toujours unique, par exemple il ne peut pas être répété?


Lorsque vous posez une question, veuillez ne pas simplement "vider vos exigences". Si vous êtes programmeur, nous nous attendons à voir votre meilleur échec. Ce faisant, vous prouvez que vous n'utilisez pas SO en tant que service de codage gratuit et les volontaires peuvent avoir plus de facilité à corriger une petite partie de votre script au lieu de créer une toute nouvelle solution. Ma philosophie SO ne me permet pas de voter pour une question sans tentative de codage.


3 Réponses :


0
votes

Avec ces données construites, cela pourrait être difficile (mais pas impossible), mais je suggérerais de les changer en tableaux multidimensionnels afin que vous ayez quelque chose comme:

$keys = [];
$for($i=0;$i<$array['floorplans'];++$i) {
    if(isset($array['floorplans_'.$i.'_valid_for_export']) && $array['floorplans_'.$i.'_valid_for_export']===1) {
        $keys[] = $i;
    }
}

print_r($keys);

Sollution brutale

Ce n'est pas la meilleure approche, mais cela devrait fonctionner si vous n'avez besoin de rien d'extraordinaire et sachez que la structure des données ne changera pas à l'avenir

[floorplans][0][valid_for_export] => 0
[floorplans][0][title] => title 1
[floorplans][0][house_area] => 40m²
[floorplans][0][bedrooms] => 1
[floorplans][1][valid_for_export] => 1
[floorplans][1][title] => title xx
[floorplans][1][house_area] => 90m²


3 commentaires

Voici le problème, c'est que je ne peux pas en changer la structure.


@AmjadKhalil j'ai ajouté une solution rought, ce n'est pas joli mais devrait faire le travail


Il est conseillé de recommander de restructurer les données entrantes - mais cela devrait être un commentaire sous la question. Le deuxième extrait de code ne fournit pas la sortie souhaitée. Ce n'est pas une bonne réponse.



5
votes

C'est un schéma étrange, mais cela peut être fait en itérant dans le tableau et en recherchant des clés où "valid_for_export" est égal à 1, puis en utilisant un autre tableau de champ "stubs" pour obtenir les éléments associés par un identifiant unique de X dans floorplans_X_valid_for_export

$array = [
    'floorplans_0_valid_for_export' => 0,
    'floorplans_0_title' => 'title 1',
    'floorplans_0_house_area' => '40m²',
    'floorplans_0_bedrooms' => 1,
    'floorplans_1_valid_for_export' => 1,
    'floorplans_1_title' => 'title xx',
    'floorplans_1_house_area' => '90m²',
    'floorplans_1_bedrooms' => '2',
    'floorplans_2_valid_for_export' => 1,
    'floorplans_2_title' => 'title 2',
    'floorplans_2_house_area' => '50m²',
    'floorplans_2_bedrooms' => 1,
    'floorplans' => 3
];


$stubs = [
     'floorplans_%s_valid_for_export',
     'floorplans_%s_title',
     'floorplans_%s_house_area',
     'floorplans_%s_bedrooms'
];

$newArr = [];

foreach ($array as $key => $value) {
    if (strpos($key, 'valid_for_export') && $array[$key] == 1) {
        $intVal = filter_var($key, FILTER_SANITIZE_NUMBER_INT);
        foreach ($stubs as $stub) {
            $search = sprintf($stub, $intVal);
            if (isset($array[$search])) {
                $newArr[$search] = $array[$search];
            } else {
                // key can't be found, generate one with null
                $newArr[$search] = null;
            }
        }
    }
}

echo '<pre>';
print_r($newArr);

Fonctionnement: http://sandbox.onlinephpfunctions.com/code/23a225e3cefa2dc9cc97f53f1cbae0ea291672c0


2 commentaires

Cette solution est de la pure poésie. La seule amélioration que je pourrais suggérer est quelques commentaires - même un codeur expérimenté devra y réfléchir. J'aime particulièrement le combo $stub / sprintf .


Il existe une manière plus propre de le faire.



2
votes

Utilisez une boucle parente pour vérifier que la valeur de valid_for_export spécifique au valid_for_export n'est pas vide, car elle est égale à 0 ou non à zéro.

Si tel est le cas, insérez simplement tous les éléments associés dans le tableau de résultats.

Certaines raisons pour lesquelles cette réponse est supérieure à la réponse de @ Alex sont:

  1. La boucle parente d'Alex fait 13 itérations (et le même nombre d' strpos() ); le mien n'en fait que 3 (et seulement 3 appels de empty() ).
  2. $array[$key] s'écrit plus simplement sous la forme $value .
  3. La désinfection de la $key pour extraire l'index / compteur est plus que nécessaire, comme démontré dans ma réponse.

Code ( démo )

array (
  'floorplans_1_valid_for_export' => 1,
  'floorplans_1_title' => 'title xx',
  'floorplans_1_house_area' => '90m²',
  'floorplans_1_bedrooms' => '2',
  'floorplans_2_valid_for_export' => 1,
  'floorplans_2_title' => 'title 2',
  'floorplans_2_house_area' => '50m²',
  'floorplans_2_bedrooms' => 1,
)

Production:

$array = [
    'floorplans_0_valid_for_export' => 0,
    'floorplans_0_title' => 'title 1',
    'floorplans_0_house_area' => '40m²',
    'floorplans_0_bedrooms' => 1,
    'floorplans_1_valid_for_export' => 1,
    'floorplans_1_title' => 'title xx',
    'floorplans_1_house_area' => '90m²',
    'floorplans_1_bedrooms' => '2',
    'floorplans_2_valid_for_export' => 1,
    'floorplans_2_title' => 'title 2',
    'floorplans_2_house_area' => '50m²',
    'floorplans_2_bedrooms' => 1,
    'floorplans' => 3
];

$labels = ['valid_for_export', 'title', 'house_area', 'bedrooms'];

$result = [];
for ($i = 0; $i < $array['floorplans']; ++$i) {
    if (!empty($array['floorplans_' . $i . '_valid_for_export'])) {
        foreach ($labels as $label) {
            $key = sprintf('floorplans_%s_%s', $i, $label);
            $result[$key] = $array[$key];
        }
    }
}
var_export($result);


5 commentaires

J'ai littéralement répondu un instant après que la réponse précédente ait été acceptée. Je souhaite que les gens soient plus patients (ou soient disposés à changer la tique) afin que les chercheurs puissent trouver plus facilement la meilleure réponse.


votre réponse est plus propre, cependant je suggérerais de vérifier textuellement si la valeur est égale à 1 et de faire quelque chose comme $result[$key] = isset($array[$key]) ? $array[$key] : null; juste pour éviter les erreurs potentielles. semble que ce schéma de base de données n'est pas correctement formaté, donc je m'attendrais pleinement à des problèmes avec les données d'OP que nous ne voyons pas


Je ne vois aucune preuve dans la question que ces préoccupations se manifesteront. Je suis d'accord que la structure des données entrantes n'est pas idéale.


Les erreurs compréhensibles, mais de "clé de tableau non définie" sont toujours tristes quand elles peuvent être facilement évitées.


C'est une préoccupation «inventée». La fusion nulle serait ma technique de choix si la menace était réelle.