Elegant Way to Search an PHP Array Using a User-Defined Function

array_search for multidimensional array with two attributes

It's probably simplest just to use a foreach over the values e.g. this function will return a similar value to array_search:

function find_user($userdb, $attributes) {
foreach ($userdb as $key => $user) {
if (empty(array_diff($attributes, $user))) return $key;
}
return false;
}

echo find_user($userdb, array('name' => 'Stefanie Mcmohn', 'uid' => 5465));

Output

1

Demo on 3v4l.org

First element of array by condition

There's no need to use all above mentioned functions like array_filter. Because array_filter filters array. And filtering is not the same as find first value. So, just do this:

foreach ($array as $key => $value) {
if (meetsCondition($value)) {
$result = $value;
break;
// or: return $value; if in function
}
}

array_filter will filter whole array. So if your required value is first, and array has 100 or more elements, array_filter will still check all these elements. So, do you really need 100 iterations instead of 1? The asnwer is clear - no.

Get code of a specific user define function or class from a source code

<?php

/**moDO(Classes)(Parsers)(parse_php)

@(Description)
Parses php code and generates an array with the code of the classes and stand-alone functions found.

@(Description){note warn}
Curly brackets outside the code structures can break the parser!

@(Syntax){quote}
object `parse_php` ( string ~$path~ )

@(Parameters)
@(Parameters)($path)
Path to the php file to be parsed.

@(Return)
Returns an object that contains a variable `parsed` that contains the resulting array.

@(Examples)
@(Examples)(1){info}
`Example 1:` Basic usage example.

@(Examples)(2){code php}
$parser = new parse_php(__FILE__);
print_r($parser->parsed);

@(Changelog){list}
(1.0) ~Initial release.~

*/

/**
* Parses php code and generates an array with the code of the classes and stand-alone functions found.
* Note: Curly brackets outside the code structures can break the parser!
* @syntax new parse_php($path);
* @path string containing path to file to be parsed
*/
class parse_php {
public $parsed = false;

/**
* Validates the path parameter and starts the parsing.
* Once parsing done it sets the result in the $parsed variable.
* @path string representing valid absolute or relative path to a file.
*/
function __construct($path) {
if(is_file($path)) {
$this->parsed = $this->load($path);
}
}

/**
* This loads prepares the contents for parsing.
* It normalizes the line endings, builds lines array and looks up the structures.
* @path string representing valid absolute or relative path to a file.
*/
private function load($path) {
$file = file_get_contents($path);
$string = str_replace(Array("\r\n", "\r", "\n"), Array("\n", "\n", "\r\n"), $file);
$array = explode("\r\n", $string);

preg_match_all('/((abstract[ ])?(function|class|interface)[ ]+'
.'[a-z_\x7f-\xff][a-z0-9_\x7f-\xff]+[ ]*(\((.+)?\)[ ]*)?)'
.'([ ]*(extends|implements)[ ]*[a-z_\x7f-\xff]'
.'[a-z0-9_\x7f-\xff]+[ ]?)?[ ]*(\r|\n|\r\n)*[ ]*(\{)/i'
, $string
, $matches);

$filtered = Array();
foreach($matches[0] AS $match) {
list($first, $rest) = explode("\r\n", $match, 2);
$filtered[] = $first;
}

return $this->parse($array, $filtered);
}

/**
* The parser that loops the content lines and builds the result array.
* It accounts for nesting and skipps all functions that belong to a class.
* @lines array with the lines of the code file.
* @matches array containing the classes and possible stand-alone functions to be looked up.
*/
private function parse($lines, $matches) {
$key = false;
$track = false;
$nesting = 0;
$structures = Array();

foreach($lines AS $line) {
if($key === false)
$key = $this->array_value_in_string($line, $matches);

if($key !== false) {
if($nesting > 0)
$track = true;

$nesting = $nesting + substr_count($line, ' {');
$nesting = $nesting - substr_count($line, ' }');

$structures[$key][] = $line;

if($track && $nesting == 0) {
$track = false;
$key = false;
}
}
}

return array_values($structures);
}

/**
* Checks if any of the (array)needles are found in the (string)haystack.
* @syntax $this->array_value_in_string($string, $array);
* @haystack string containing the haystack subject of the search.
* @needles array containing the needles to be searched for.
*/
private function array_value_in_string($haystack, $needles) {
foreach($needles AS $key => $value) {
if(stristr($haystack, $value))
return $key;
}
return false;
}
}

/**
* Example execute self
*/
header('Content-type: text/plain');
$parser = new parse_php('test.php');
print_r($parser->parsed);

Is there an elegant way to reduce an structure to a simple array?

You can use array_column to extract all values with key name into another array

$names = array_column($strut['resources'][0]['schema']['fields'], 'name');

elegant way to extract values from array

You can use array_map with anonymous functions:

// PHP 5.2
$extractedTags = array_map(create_function('$a', 'return $a["tag"];'), $article['Tags']);

// PHP 5.3
$extractedTags = array_map(function($a) { return $a['tag']; }, $article['Tags']);

How to merge and sort array in php with custom or user-defined criteria?

$data = array_merge($data1, $data2);
$data = array_filter($data, function ($d) {
return $d['amount'] != 0;
});
usort($data, function ($a, $b) {
if ($a['id'] != $b['id']) return $a['id'] - $b['id'];
if ($a['level'] != $b['level']) return $a['level'] - $b['level'];
else return $a['index'] - $b['index'];
});

Note: Uses PHP 5.3+ anonymous function syntax.

PHP array_diff with instances or custom callback function?

Does this mean I'm forced to implement toString() in my instances?

According to the typecast section in the PHP docs manual - you do not need a toString() function. Basically typecasting (string) is the same as if you simply did var_dump($uniqueProducts)

All that the array_diff is doing is typecasting your array.

One option is to make your own "array_diff" function

function my_array_diff($arraya, $arrayb)
{
foreach ($arraya as $keya => $valuea)
{
// Put your own 'test' here - but for example this uses in_array()
if (in_array($valuea, $arrayb))
{
unset($arraya[$keya]);
}
}
return $arraya;
}

Use an array as an index to access a multidimensional array in PHP

Suppose you have the array like below

<?php
$a = array(
12 => array(
65 => array(
90 => array(
'Children' => array()
)
)
)
);

$param = array(12, 65, 90); // your function should return values like this
$x =& $a; //we referencing / aliasing variable a to x
foreach($param as $p){
$x =& $x[$p]; //we step by step going into it
}
$x['Children'] = 'asdasdasdasdas';
print_r($a);

?>`

You can try referencing or aliasing it


http://www.php.net/manual/en/language.references.whatdo.php

The idea is to make a variable which is an alias of your array and going deep from the variable since we can't directly assigning multidimensional key from string (AFAIK)



output

Array
(
[12] => Array
(
[65] => Array
(
[90] => Array
(
[Children] => asdasdasdasdas
)

)

)

)


Related Topics



Leave a reply



Submit