In PHP I have a set of nested arrays of data. I want to flatten these, so that for every node and leaf I get a list of its parents.
Here’s an example of the original array – note, each part could be of an unknown depth and length:
$data = array( "name" => "Thing", "children" => array( array( "name" => "Place", "rdfs:subClassOf" => "schema:Thing", "children" => array( array( "name" => "Accomodation", "rdfs:subClassOf" => "schema:Place", "children" => array( array( "name" => "Apartment", "rdfs:subClassOf" => "schema:Accomodation", ), array( "name" => "Hotel", "rdfs:subClassOf" => "schema:Accomodation", ), array( "name" => "House", "rdfs:subClassOf" => "schema:Accomodation", ) ) ) ) ), array( "name" => "CreativeWork", "rdfs:subClassOf" => "schema:Thing", "children" => array( array( "name" => "Article", "rdfs:subClassOf" => "schema:CreativeWork", "children" => array( array( "name" => "NewsArticle", "rdfs:subClassOf" => "schema:Article", ), array( "name" => "OpinionArticle", "rdfs:subClassOf" => "schema:Article", ), ) ) ) ) ) );
(The data I’m actually parsing is this Schema.org JSON file – the above is a minimal example of it.)
And here’s what I’d like to end up with:
$results = array( "Place" => array("Thing"), "Accomodation" => array("Thing", "Place"), "Apartment" => array("Thing", "Place", "Accomodation"), "Hotel" => array("Thing", "Place", "Accomodation"), "House" => array("Thing", "Place", "Accomodation"), "CreativeWork" => array("Thing"), "Article" => array("Thing", "CreativeWork"), "NewsArticle" => array("Thing", "CreativeWork", "Article"), "OpinionArticle" => array("Thing", "CreativeWork", "Article"), );
I’m assuming I need to recursively call a function to build the array but so far I’m not having much luck. In case this makes it harder, this is happening in a static method.
Advertisement
Answer
Something quick to get you started:
class Parser { public static function parse($input,$prefix = []) { $return = $prefix ? [$input['name']=>$prefix] : []; if (isset($input['children'])) { $prefix[] = $input['name']; foreach ($input['children'] as $child) { $return += self::parse($child,$prefix); } } return $return; } } var_dump(Parser::parse($data));
You probably need to add a few checks and comments to make it more readable.