[PHP] Array checken op meer fields

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Stel, ik heb de volgende array:
PHP:
1
2
3
4
5
6
7
8
9
10
11
$product_fields = array(
  'modified' => 434325325,
  'title' => 'dit is de titel',
  'body' => 'dit is de body',
  'price' => '54,95',
  'promoted' => 1
);

$standard_fields = array(
  'modified', 'title', 'promoted'
);

Als ik $product_fields vergelijk met $standard_fields, zie ik al snel dat 'body' en 'price' velden zijn die wel in $product_fields zitten maar niet in $standard_fields. Is er een manier om snel de keys van $products_fields te vergelijken met $standard_fields en true teruggeven als er meer en andere keys in zitten dan in $standard_fields?

Ik kan dit natuurlijk oplossen met een foreach loop, maar wellicht kan het eenvoudiger? Ik moet de bewerking namelijk vaak uitvoeren per request...

Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 15:29

crisp

Devver

Pixelated

array_diff en array_keys zijn je vriend gok ik zo

Intentionally left blank


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
crisp schreef op dinsdag 25 november 2008 @ 23:14:
array_diff en array_keys zijn je vriend gok ik zo
Daar zit hem het probleem: $standard_fields zijn values (geen keys), maar $product_fields zijn key => value paren. Eigenlijk zijn de arrays dus als volgt:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
$product_fields = array(
  'modified' => 434325325,
  'title' => 'dit is de titel',
  'body' => 'dit is de body',
  'price' => '54,95',
  'promoted' => 1
);

$standard_fields = array(
  0 => 'modified',
  1 => 'title'
  2 => 'promoted'
);

Ik wil dus:
  • de keys van $products_fields vergelijken met de values van $standard_fields
  • als $product_fields niet minstens alle keys uit $standard_fields bevat, wil ik deze retourneren
  • als $product_fields meer velden bevat dan $standard_fields, wil ik die keys retourneren
  • in dit geval zou de return array('body', 'price') zijn
Nog een voorbeeld:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
$product_fields = array(
  'title' => 'dit is de titel',
  'body' => 'dit is de body',
  'price' => '54,95',
  'promoted' => 1
);

$standard_fields = array(
  0 => 'modified',
  1 => 'title'
  2 => 'promoted'
);

In dit geval ontbreekt het (verplichte, standaard) veld "modified", dus moet de return array('modified') zijn.
Dat is imho niet met standaard functies op te lossen...?

[ Voor 86% gewijzigd door Verwijderd op 25-11-2008 23:50 ]


Acties:
  • 0 Henk 'm!

  • Thomasje
  • Registratie: Augustus 2002
  • Laatst online: 29-05-2024

Thomasje

Semacode

Zou gewoon een functie schrijven die de $standard_fields uitleest en dan checkt of die velden bestaan. Standaard functies zijn hier niet voor. Waarom moet $standard_fields een numerieke key hebben?

Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

PHP:
1
2
3
4
5
6
7
8
9
$nonExistant = new array();
foreach($standard_fields as $key => $value)
{
   //the $value is the key of the $product_field
   if(!array_key_exists($value, $product_fields))
      $nonExistant[] = $value;
}

//$nonExistant is what you want

[ Voor 33% gewijzigd door Snake op 26-11-2008 00:10 ]

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

  • Patriot
  • Registratie: December 2004
  • Laatst online: 16-09 13:49

Patriot

Fulltime #whatpulsert

Of korter:

PHP:
1
2
3
4
5
<?php

$missing = array_diff($standard_fields, array_keys($product_fields));

?>


Je hebt dan de waarden niet zoals bij Snake, maar daar vroeg je ook niet om.
Thomasje schreef op dinsdag 25 november 2008 @ 23:57:
Zou gewoon een functie schrijven die de $standard_fields uitleest en dan checkt of die velden bestaan. Standaard functies zijn hier niet voor. Waarom moet $standard_fields een numerieke key hebben?
Ze moeten dat niet hebben, maar hebben dat wel standaard. Even opnieuw lezen, lijkt me namelijk dat je wel weet dat die keys standaard zo zijn.

EDIT:
Het moge overigens duidelijk zijn dat crisp dit antwoord natuurlijk in de tweede post al gaf. Je geeft zelf al aan dat je alleen de keys uit $product_fields wilde hebben, en laat array_keys daar nou verantwoordelijk voor zijn.

[ Voor 15% gewijzigd door Patriot op 26-11-2008 00:23 . Reden: nadruk; toevoeging ]


Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

Patriot schreef op woensdag 26 november 2008 @ 00:18:
Of korter:

PHP:
1
2
3
4
5
<?php

$missing = array_diff($standard_fields, array_keys($product_fields));

?>


Je hebt dan de waarden niet zoals bij Snake, maar daar vroeg je ook niet om.


[...]


Ze moeten dat niet hebben, maar hebben dat wel standaard. Even opnieuw lezen, lijkt me namelijk dat je wel weet dat die keys standaard zo zijn.
Inderdaad, kan je er geen object van maken, waarbij bepaalde waarden null zijn als ze niet bestaan?

Dat lijkt me veel eenvoudiger. Beetje OO programmeren :)

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik kom er niet helemaal uit, daarom heb ik voor mezelf duidelijk uitgeschreven wat ik wil:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
function check_fields($fields) {
  $standard_fields = array('modified', 'title', 'promoted');
  if (isset($fields['nid'])) {
    // 1. check if $fields contains any of the $standard_fields
    $fields = array_intersect_key($fields, array_keys($standard_fields));
    // if true: call update_node($fields)
    // 2. check if there are any additional fields in $fields that are not in $standard_fields
    // if true:
    //     3. put them in an array: $additional_fields
    //     call node_extra($additional_fields)
  }
  else {
    set_error("no nid defined");
  }
}

$fields = array( 
  'nid' => 4,
  'modified' => 434325325, 
  'title' => 'dit is de titel', 
  'price' => '54,95', 
  'promoted' => 1 
); 

check_fields($fields);

// should output:
// update_node($fields);
// $additional_fields = array('body' => 'dit is de body', 'price' => '54,95')
// node_extra($additional_fields);


Om 1. op te lossen, probeerde ik regel 5, maar dit levert een lege array op. Ook als ik de argumenten omdraai. Kan iemand mij uitleggen waarom? Er zou toch array('modified', 'title', 'promoted') uit moeten komen?

Acties:
  • 0 Henk 'm!

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 06-09 00:37

curry684

left part of the evil twins

array_keys retourneert alle keys van een array als een array met values. Zorg er even voor dat je het concept 'keys' en 'values' goed in je kop hebt zitten want volgens mij schort het je daaraan ;)

Professionele website nodig?


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
curry684 schreef op woensdag 26 november 2008 @ 13:53:
array_keys retourneert alle keys van een array als een array met values. Zorg er even voor dat je het concept 'keys' en 'values' goed in je kop hebt zitten want volgens mij schort het je daaraan ;)
Oeps:
PHP:
1
$filtered_fields = array_intersect($node_fields, array_keys($node));

Mooi :)

Nu een vraag (voorbeeld met andere variabelen, maar maakt niet uit):
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$node = array(
  'nid' => 7,
  'modified' => 545346343,
  'sticky' => 1,
  'body' => 'blaat'
);
$node_fields = array('title', 'modified', 'comment', 'promote', 'sticky');
$matching_fields = array_intersect($node_fields, array_keys($node));

/*
$matching_fields = array(
  1 => 'modified',
  4 => 'sticky'
);
*/

Nu wil ik de non-matching fields (nid en body) ook in een array hebben. Dus eigenlijk: $non_matching_fields = $node - $matching_fields. Nu kan dat met een foreach loop, maar kan het niet met minder code? Ik dacht aan array_filter, maar die gebruikt een callback, en dan moet ik weer een aparte functie daarvoor definieren, dus dat scheelt dan weer niks. Hoe kan ik argumenten aan die callback meegeven? Want dan zou ik iets als dit kunnen doen:
PHP:
1
$non_matching_fields = array_filter($node, "!in_array($matching_fields)");

Of moet het toch met een loop?

Acties:
  • 0 Henk 'm!

  • Patriot
  • Registratie: December 2004
  • Laatst online: 16-09 13:49

Patriot

Fulltime #whatpulsert

Sorry hoor, maar als ik je stukje code zie, dan zie ik dat in check_fields() het tegenovergestelde gebeurt van wat jij in de topicstart vraagt. In de topicstart vraag jij om de elementen van B die niet in A staan. In de check_fields die jij geeft, vraag je alle elementen van A die óók in B staan op. Je wilt dus dit:

PHP:
1
2
3
4
5
<?php

$non_matching_fields = array_diff(array_keys($node), $matching_fields);

?>


Dat geeft alle keys van $node die niet in $matching_fields staan.
Pagina: 1