10
votes

Référence Tableau PHP par plusieurs index

Ceci peut être une sorte de raccourci étrange plus étrange et corrigez-moi si je me trompe dans ce train de pensée ...

J'ai une matrice de données qui ressemble à: P>

unique_id | url | other random data...
unique_id | url | other random data...
unique_id | url | other random data...


3 commentaires

Non, pas vraiment. Il suffit de faire deux tableaux. Les frais généraux sont minimes (bien, en fonction de la taille de vos matrices).


Avez-vous besoin de modifier les "données aléatoires" une fois qu'il est dans la matrice? Et il est possible d'une connexion unique_id et une URL?


Ne Dupliquer "Autres données aléatoires" (concept "sec"). La solution la plus propre consiste à disposer d'une matrice qui mappe unique_id à d'autres données aléatoires , puis un second tableau qui mappe url à unique_id < / code>. C'est le but de unique_id s: pour fournir une "poignée" concise et efficace qui représente un enregistrement donné (rangée) de données.


4 Réponses :


3
votes

Essayez quelque chose comme ceci:

function selectByIdOrURL($array, $data) {
    foreach($array as $row) {
       if($row['unique_id'] == $data || $row['url'] == $data) return $row;
    }
    return NULL;
}

$array = array(
           array('unique_id' => 5, 'url' => 'http://blah.com'),
           array('unique_id' => 3, 'url' => 'http://somewhere_else.com')
         );
$found = selectByIdOrURL($array, 5); //array('unique_id' => 5, 'url' => 'http://blah.com')
$nfound = selectByIdOrURL($array, 10); //NULL


5 commentaires

Est le seul moyen de parcourir les données? Je suppose que ce n'est pas une affaire énorme, mais je suis vraiment curieux si vous pouvez avoir plusieurs index pour les tableaux (en général)


@Bob, non, il n'y a aucun moyen d'avoir plusieurs index pour les tableaux.


De manière générale, non. L'approche la plus rapide (pour les temps d'accès) est d'avoir deux matrices, une avec l'unique_id comme clé, l'autre avec l'URL, et à la fois avec toutes les données comme valeur. La réponse de Jacob utilisera un peu moins de mémoire, mais devra itérer l'ensemble de la matrice à chaque fois que vous faites référence à quelque chose; Mon approche utilisera légèrement plus de mémoire, mais récupérera les résultats plus rapidement.


C'est une honte ... je suppose que je ne suis pas si mauvais


Toute solution fantaisie impliquerait de toute façon une itération dans les coulisses.



14
votes

Seulement, je peux penser que cela n'implique pas de itération de la matrice pour chaque recherche (voir la réponse de Jacob) consiste à stocker des références à chaque élément de deux tableaux.

EDIT : Les URL et les identifiants ne peuvent pas entrer en collision, ils peuvent être stockés dans le même tableau de référence (merci Matthew) xxx

Vous pouvez probablement encapsuler suffisamment d'une classe de collection qui implémente GetByID () et getByurl () . En interne, cela pourrait stocker les références dans autant de réseaux que nécessaire.

Bien sûr, ce que vous faites essentiellement ici consiste à créer des ensembles de résultats indexés, ce qui reste mieux à gauche aux systèmes de gestion de base de données.


4 commentaires

De plus, vous pouvez les mettre dans le même tableau (E.G. $ éléments ) si vous le souhaitez. Cela peut être légèrement déroutant, mais Bob a déclaré que les clés ne peuvent pas entrer en collision.


Oh c'est intéressant. Ils ne sont pas entrés en collision, mais il semble un peu effrayant d'un point de support de vulnérabilité (par exemple, une recherche qui a été forcée à l'aide d'une URL au lieu d'un fichier unique. Belle technique bien que


@BOB Il est similaire à quand vous récupérez des enregistrements de base de données à l'aide d'un fetch_both méthode où le résultat contient des index numériques et de chaîne. En parlant d'index, si ces données proviennent d'une DB, vous préférez probablement mieux appliquer des index dans les champs ID et URL et faire des extratures à une seule extraction pour récupérer des enregistrements nominés.


@Matthewflaschen - vous pourrait les mettre dans le même tableau, mais son nettoyeur d'avoir un deuxième tableau qui mappe URL à unique_id . Gardez des concepts distincts séparés.



0
votes

Sûrement d'un objet serait le moyen facile?

$itemArray = new ItemArray();
$item = new Item("someURL", "someUniqueURL","some other crap");
$itemArray->push($item);

$retrievedItem = $itemArray->getItemByURL("someURL");


0 commentaires

1
votes

Il apparaît que votre solution fantaisie n'était disponible que de PHP 5.5 forte>. Vous pouvez combiner l'utilisation de Array_search et array_column Pour aller chercher votre entrée dans une seule ligne de code:

$items = [
    [
     'unique_id' => 42,
     'url' => 'http://foo.com'
    ],
    [
     'unique_id' => 57,
     'url' => 'http://bar.com'
    ],
    [
     'unique_id' => 36,
     'url' => 'http://example.com'
    ],

];

$bar = $entries[array_search(57, array_column($items, 'unique_id'))];

var_dump($bar);

//outputs
array (size=2)
    'unique_id' => int 57
    'url' => string 'http://bar.com' (length=14)


0 commentaires