1
votes

Manipulation du tableau php

J'ai besoin de créer une structure de chemin, avec les valeurs que j'obtiens du tableau:

Array
(
    [0] => TTT 1000 S/Certificate/English
    [1] =>TTT 1000 S/Certificate/Spanish
    [2] => TTT 1100 S/Certificate/English
    [3] => TTT 1100 S/Certificate/Spanish
)

Donc, je dois créer un chemin qui ressemble à ceci:

Array
(
    [machineAttribute] => Array
    (
        [0] => TTT 1000 S
        [1] => TTT 1100 S
        [2] => TTT 1200 S
    )

    [technicalAttribute] => Certificate

    [languageAttribute] => Array
    (
        [0] => English
        [1] => Spanish
    )

)

C'est un scénario parfait et j'ai pu résoudre cela avec foreach imbriqué:

if (is_array($machineAttributePath))
{
    foreach ($machineAttributePath as $machinePath)
    {
        if (is_array($technicalAttributePath))
        {
            foreach ($technicalAttributePath as $technicalPath)
            {

                if (is_array($languageAttributePath))
                {
                    foreach ($languageAttributePath as $languagePath)
                    {
                        $multipleMachineValuesPath[] = $machinePath . '/' . $technicalPath . '/' . $languagePath);
                    }
                }

            }
        }
    }

    return $multipleMachineValuesPath;
}

Mais, le problème commence, si le tableau retourne valeurs mixtes, parfois, valeur unique, parfois tableau. Par exemple:

Array
(
    [0] => TTT 1000 S/Certificate/English
    [1] => TTT 1000 S/Certificate/Spanish
    [2] => TTT 1000 S/Software/English
    [3] => TTT 1000 S/Software/Spanish
    [4] => TTT 1100 S/Certificate/English
    [5] => TTT 1100 S/Certificate/Spanish
    [6] => TTT 1100 S/Software/English
    [7] => TTT 1100 S/Software/Spanish
)  

Ensuite, le tableau devrait ressembler à:

Array
(
    [machineAttribute] => Array
    (
        [0] => TTT 1000 S
        [1] => TTT 1100 S
    )

    [technicalAttribute] => Array
    (
        [0] => Certificate
        [1] => Software
    )

    [languageAttribute] => Array
    (
        [0] => English
        [1] => Spanish
    )

)

J'ai écrit du code, mais il est vraiment désordonné et longtemps et ne fonctionne pas correctement. Je suis sûr que cela pourrait être simplifié, mais j'ai suffisamment de connaissances pour résoudre ce problème. Si quelqu'un sait comment gérer cette situation, veuillez aider. Merci.


2 commentaires

S'il s'agit d'une valeur unique, quelle est votre sortie souhaitée? Voulez-vous ajouter cette valeur unique dans tous les chemins?


C'est une bonne question, j'ai ajouté la réponse en code édité.


5 Réponses :


0
votes

Vous pouvez faire de cette façon aussi sans gâcher. Créez simplement le cartésien de votre tableau d'entrée et enfin implosez le tableau généré avec / . J'espère que cela aidera :)

<?php
function cartesian($input) {
    $result = array();

    while (list($key, $values) = each($input)) {

        if (empty($values)) {
            continue;
        }
        if (empty($result)) {
            foreach($values as $value) {
                $result[] = array($key => $value);
            }
        }
        else {

            $append = array();

            foreach($result as &$product) {

                $product[$key] = array_shift($values);
                $copy = $product;
                foreach($values as $item) {
                    $copy[$key] = $item;
                    $append[] = $copy;
                }
                array_unshift($values, $product[$key]);
            }
            $result = array_merge($result, $append);
        }
    }

    return $result;
}

$data = array
(
    'machineAttribute' => array
    (
        'TTT 1000 S',
        'TTT 1100 S'
    ),

    'technicalAttribute' => array
    (
        'Certificate',
        'Software'
    ),

    'languageAttribute' => array
    (
        'English',
        'Spanish',
    )

);

$combos = cartesian($data);
$final_result = [];
foreach($combos as $combo){
    $final_result[] = implode('/',$combo);
}
print_r($final_result);

DÉMO: https: / /3v4l.org/Zh6Ws


1 commentaires

Merci pour ça. C'est une grave manipulation de tableau. J'ai testé votre démo, cela fonctionne bien avec les valeurs de tableau, mais il y a des erreurs quand il y a une seule valeur, cependant je vais essayer d'adopter le code. Merci pour cette excellente idée!



0
votes

Si vous avez besoin de quelque chose de simple, vous pouvez convertir vos valeurs scalaires en tableau en écrivant une simple fonction séparée (appelons-la "force_array"). La fonction qui encapsule l'argument en tableau s'il ne l'est pas déjà.

function force_array($i) { return is_array($i) ? $i : array($i); }

//...

foreach (force_array($machineAttributePath) as $machinePath)
{
    foreach (force_array($technicalAttributePath) as $technicalPath)
    {
        foreach (force_array($languageAttributePath) as $languagePath)
        {
            $multipleMachineValuesPath[] = $machinePath . '/' . $technicalPath . '/' . $languagePath;
        }
    }
}

return($multipleMachineValuesPath);


1 commentaires

Ce code fonctionne très bien. J'ai réduit plus de 200 lignes de code à 10 :). Merci Serge.



0
votes

Cela résoudra presque votre problème.

$arr['machineAttribute'] = (array) $arr['machineAttribute'];
$arr['technicalAttribute'] = (array) $arr['technicalAttribute'];
$arr['languageAttribute'] = (array) $arr['languageAttribute'];

$machCount = count($arr['machineAttribute']);
$techCount = count($arr['technicalAttribute']);
$langCount = count($arr['languageAttribute']);

$attr = [];
for($i=0;$i<$machCount;$i++) {
    $attr[0] = $arr['machineAttribute'][$i] ?? "";
    for($j=0;$j<$techCount;$j++) {
        $attr[1] = $arr['technicalAttribute'][$j] ?? "";
        for($k=0;$k<$langCount;$k++) {
            $attr[2] = $arr['languageAttribute'][$k] ?? "";
            $pathArr[] = implode('/',array_filter($attr));
        }
    }
}

print_r($pathArr);


1 commentaires

Cela fonctionne aussi, excellente solution, merci Tamilvanan pour votre aide!



2
votes

Vous pouvez convertir n'importe quelle valeur en tableau juste par

foreach((array) $something....

Dans le même temps, si $ val est déjà un tableau, il ne sera pas modifié

Donc, vous pouvez tout changer un peu pour chacun

  (array) $val


1 commentaires

Génial et si simple ... :) Essayé et fonctionne comme un charme., $ pathArr = array (); foreach ($ arr ['machineAttribute'] as $ m) {foreach ($ arr ['technicalAttribute'] as $ t) {foreach ((array) $ arr ['languageAttribute'] as $ l) {$ pathArr [] = imploser ('/', tableau ($ m, $ t, $ l)); }}}



0
votes

Cela fonctionne aussi!

$results = [[]];

    foreach ($arrays as $index => $array) {
      $append = [];
      foreach ($results as $product) {
        foreach ($array as $item) {
            $product[$index] = $item;
            $append[] = $product;
        }
      }
      $results = $append;
    }
    print_r(array_map(function($arr){ return implode('/',$arr);},$results));


0 commentaires