I need to build an tree (with arrays) from given urls.
I have the following list of urls:
http://domain.com/a/a.jsp
http://domain.com/a/b/a.jsp
http://domain.com/a/b/b.jsp
http://domain.com/a/b/c.jsp
http://domain.com/a/c/1.jsp
http://domain.com/a/d/2.jsp
http://domain.com/a/d/a/2.jsp
now i need an array like this:
domain.com
a
a.jsp
b
a.jsp
b.jsp
c.jsp
c
1.jsp
d
2.jsp
a
2.jsp
How can i do this with php?
i thought mark's solution was a bit complicated so here's my take on it:
(note: when you get to the filename part of the URI, I set it as both the key and the value, wasn't sure what was expected there, the nested sample didn't give much insight.)
<?php
$urls = array(
'http://domain.com/a/a.jsp',
'http://domain.com/a/b/a.jsp',
'http://domain.com/a/b/b.jsp',
'http://domain.com/a/b/c.jsp',
'http://domain.com/a/c/1.jsp',
'http://domain.com/a/d/2.jsp',
'http://domain.com/a/d/a/2.jsp'
);
$array = array();
foreach ($urls as $url)
{
$url = str_replace('http://', '', $url);
$parts = explode('/', $url);
krsort($parts);
$line_array = null;
$part_count = count($parts);
foreach ($parts as $key => $value)
{
if ($line_array == null)
{
$line_array = array($value => $value);
}
else
{
$temp_array = $line_array;
$line_array = array($value => $temp_array);
}
}
$array = array_merge_recursive($array, $line_array);
}
print_r($array);
?>
$urlArray = array( 'http://domain.com/a/a.jsp',
'http://domain.com/a/b/a.jsp',
'http://domain.com/a/b/b.jsp',
'http://domain.com/a/b/c.jsp',
'http://domain.com/a/c/1.jsp',
'http://domain.com/a/d/2.jsp',
'http://domain.com/a/d/a/2.jsp'
);
function testMapping($tree,$level,$value) {
foreach($tree['value'] as $k => $val) {
if (($val == $value) && ($tree['level'][$k] == $level)) {
return true;
}
}
return false;
}
$tree = array();
$i = 0;
foreach($urlArray as $url) {
$parsed = parse_url($url);
if ((!isset($tree['value'])) || (!in_array($parsed['host'],$tree['value']))) {
$tree['value'][$i] = $parsed['host'];
$tree['level'][$i++] = 0;
}
$path = explode('/',$parsed['path']);
array_shift($path);
$level = 1;
foreach($path as $k => $node) {
if (!testMapping($tree,$k+1,$node)) {
$tree['value'][$i] = $node;
$tree['level'][$i++] = $level;
}
$level++;
}
}
echo '<pre>';
for ($i = 0; $i < count($tree['value']); $i++) {
echo str_repeat(' ',$tree['level'][$i]*2);
echo $tree['value'][$i];
echo '<br />';
}
echo '</pre>';
Related
I have a URL, e.g:
https://www.example.com/my-product-name-display/ex/BYADE3323/wgsi?nfh3420000ooo2323nfnf/.
From the above URL, I want to extract my-product-name-display if this URL contains it, if not, I want the string after /ex/{BYADE3323} as below URL does not contain my-product-name-display.
https://www.example.com/ex/BYADE3323/wgsi?nfh3420000ooo2323nfnf/
I have tried below code:
`$url_param = "https://www.example.com/ex/BYADE3323/wgsi?nfh3420000ooo2323nfnf/";`
or
`$url_param = "https://www.example.com/my-product-name-display/ex/BYADE3323/wgsi?nfh3420000ooo2323nfnf/";`
$e_product_title = explode('.com/', $url_param);
if(isset($e_product_title)){
$product_title = $e_product_title[1];
//now explode the ex
$get_asin = explode('/ex/',$product_title);
$final_product_title = str_replace('-',' ',$get_asin[0]);
$get_asin_final = explode('/', $get_asin[1]);
$asin_v2 = $get_asin_final[0];
}
else{
$get_asin = explode('/ex/',$url_param);
print_r($get_asin);
}
echo $final_product_title." ".$asin_v2;
Thanks in advance.
You can explode() the string,
Check if my-product-name-display and BYADE3323 is in the array.
If present, find out BYADE3323's index.
Add 1 to it and check if the next element is present.
<?php
$str = 'https://www.example.com/my-product-name-display/ex/BYADE3323/wgsi?nfh3420000ooo2323nfnf/';
$str = str_replace('://', '__', $str);
$arr = explode('/', $str);
$return = '';
if (in_array('my-product-name-display', $arr) && in_array('BYADE3323', $arr)) {
$idx = array_search('BYADE3323', $arr);
$idx2 = $idx + 1;
if (! empty($idx) && ! empty($arr[$idx2])) {
$idx += 1;
$return = $arr[$idx2];
}
}
echo $return;
EDIT:
As per comments from OP, following is the program for array of urls and array of search strings.
<?php
$searchStrings = [];
$searchStrings[] = ['my-product-name-display', 'BYADE3323'];
$searchStrings[] = ['your-product-name-display', 'BYADE4434'];
$urls = [];
$urls[] = 'https://www.example.com/my-product-name-display/ex/BYADE3323/wgsi?nfh3420000ooo2323nfnf/';
$urls[] = 'https://www.example.com/your-product-name-display/ex/BYADE4434/wgsi?nfh3420000ooo2323nfnf/';
$urls[] = 'https://www.example.com/their-product-name-display/ex/TEST343/wgsi?nfh3420000ooo2323nfnf/';
$urls[] = 'https://www.example.com/my-product-name-display/ex/ANASDF33/wgsi?nfh3420000ooo2323nfnf/';
$urls[] = 'https://www.example.com/my-product-name-display/ex/BYADE3323/wgsi?nfh3420000ooo2323nfnf/';
$return = [];
if (! empty($urls)) {
foreach ($urls as $url) {
if (! empty($searchStrings)) {
foreach ($searchStrings as $searchString) {
$str = implode('/ex/', $searchString);
if (strpos($url, $str) !== false) {
$arr = explode('/', $url);
$idx = array_search('BYADE3323', $arr);
$idx2 = $idx + 1;
if (! empty($idx) && ! empty($arr[$idx2])) {
$idx += 1;
$return[] = $arr[$idx2];
}
}
}
}
}
}
echo '<pre>';
print_r($return);
echo '</pre>';
Output:
Array
(
[0] => wgsi?nfh3420000ooo2323nfnf
[1] => wgsi?nfh3420000ooo2323nfnf
)
Try this to fetch from URL values.
pass url to the function. You can extract it.
Here is the URL :
https://www.example.com/my-product-name-display/ex/BYADE3323/wgsi?nfh3420000ooo2323nfnf/
So when u want only BYADE3323 this value.
When you print $parts array, you can find every values after your Host name.
Where your host name is https://www.example.com.
function GetStringAfterSecondSlashInURL($the_url)
{
$parts = explode("/",$the_url,3);
if(isset($parts[2]))
return $parts[2];
}
Use parse_url() function this will help you definitely.
You can refer it from official PHP site: parse-url.
You can use strpos to identify weather 'my-product-name-display' is exist s in url or not and execute code accordingly.
strpos($url_param, 'my-product-name-display') !== false
Modified code:
function get_product_title($url_param) {
$get_asin = explode('/ex/', $url_param);
$get_asin_final = explode('/', $get_asin[1]);
$asin_v2 = $get_asin_final[0];
return $asin_v2;
}
$url_param = "https://www.example.com/ex/BYADE3323/wgsi?nfh3420000ooo2323nfnf/";
$url_param = "https://www.example.com/my-product-name-display/ex/BYADE3323/wgsi?nfh3420000ooo2323nfnf/";
$product_name = '';
if (strpos($url_param, 'my-product-name-display') !== false) {
$e_product_title = explode('.com/', $url_param);
if (isset($e_product_title)) {
$product_title = $e_product_title[1];
//now explode the ex
$product_name = get_product_title($product_title);
}
echo "my product name display" . $product_name;
}
else {
$product_name = get_product_title($url_param);
echo $product_name;
}
$array = ['coke.','fanta.','chocolate.'];
foreach ($array as $key => $value) {
if (strlen($value)<6) {
$new[] = $value." ".$array[$key+1];
} else {
$new[] = $value;
}
}
This code doesn't have the desired effect, in fact it doesn't work at all. What I want to do is if an array element has string length less than 5, join it with the next element. So in this case the array should turn into this:
$array = ['coke. fanta.','chocolate.'];
$array = ['coke.','fanta.','chocolate.', 'candy'];
$new = [];
reset($array); // ensure internal pointer is at start
do{
$val = current($array); // capture current value
if(strlen($val)>=6):
$new[] = $val; // long string; add to $new
// short string. Concatenate with next value
// (note this moves array pointer forward)
else:
$nextVal = next($array) ? : '';
$new[] = trim($val . ' ' . $nextVal);
endif;
}while(next($array));
print_r($new); // what you want
Live demo
With array_reduce:
$array = ['coke.', 'fanta.', 'chocolate.', 'a.', 'b.', 'c.', 'd.'];
$result = array_reduce($array, function($c, $i) {
if ( strlen(end($c)) < 6 )
$c[key($c)] .= empty(current($c)) ? $i : " $i";
else
$c[] = $i;
return $c;
}, ['']);
print_r($result);
demo
<pre>
$array = ['coke.','fanta.','chocolate.'];
print_r($array);
echo "<pre>";
$next_merge = "";
foreach ($array as $key => $value) {
if($next_merge == $value){
continue;
}
if (strlen($value)<6) {
$new[] = $value." ".$array[$key+1];
$next_merge = $array[$key+1];
} else {
$new[] = $value;
}
}
print_r($new);
</pre>
Updated Code after adding pop after chocolate.
<pre>
$array = ['coke.','fanta.','chocolate.','pop'];
print_r($array);
echo "<br>";
$next_merge = "";
foreach ($array as $key => $value) {
if($next_merge == $value){
continue;
}
if (strlen($value)<6 && !empty($array[$key+1])) {
$new[] = $value." ".$array[$key+1];
$next_merge = $array[$key+1];
} else {
$new[] = $value;
}
}
print_r($new);
<pre>
You need to skip the iteration for the values that you have already added.
$array = ['coke.', 'fanta.', 'chocolate.'];
$cont = false;
foreach ($array as $key => $value) {
if ($cont) {
$cont = false;
continue;
}
if (strlen($value) < 6 && isset($array[$key+1])) {
$new[] = $value.' '.$array[$key+1];
$cont = true;
}
else {
$new[] = $value;
}
}
print_r($new);
I have a comma separated string like
$str = "word1,word2,word3";
And i want to make a parent child relationship array from it.
Here is an example:
Try this simply making own function as
$str = "word1,word2,word3";
$res = [];
function makeNested($arr) {
if(count($arr)<2)
return $arr;
$key = array_shift($arr);
return array($key => makeNested($arr));
}
print_r(makeNested(explode(',', $str)));
Demo
function tooLazyToCode($string)
{
$structure = null;
foreach (array_reverse(explode(',', $string)) as $part) {
$structure = ($structure == null) ? $part : array($part => $structure);
}
return $structure;
}
Please check below code it will take half of the time of the above answers:
<?php
$str = "sports,cricket,football,hockey,tennis";
$arr = explode(',', $str);
$result = array();
$arr_len = count($arr) - 1;
$prev = $arr_len;
for($i = $arr_len; $i>=0;$i--){
if($prev != $i){
$result = array($arr[$i] => $result);
} else {
$result = array ($arr[$i]);
}
$prev = $i;
}
echo '<pre>',print_r($result),'</pre>';
Here is another code for you, it will give you result as you have asked :
<?php
$str = "sports,cricket,football,hockey,tennis";
$arr = explode(',', $str);
$result = array();
$arr_len = count($arr) - 1;
$prev = $arr_len;
for($i = $arr_len; $i>=0;$i--){
if($prev != $i){
if($i == 0){
$result = array($arr[$i] => $result);
}else{
$result = array(array($arr[$i] => $result));
}
} else {
$result = array ($arr[$i]);
}
$prev = $i;
}
echo '<pre>',print_r($result),'</pre>';
$arr['animal'][0] = 'Dog';
$arr['animal'][1] = 'Cat';
From that array basically I need to create a function with the array value parameter and then it gives me the array keys.
For example:
find_index('Cat');
Output :
The result is animal, 1
You could probably do something like
function find_index($value) {
foreach ($arr as $index => $index2) {
$exists = array_search($value, $index2);
if ($exists !== false) {
echo "The result is {$index}, {$exists}";
return true;
}
}
return false;
}
Try this:
$arr['animal'][0] = 'Dog';
$arr['animal'][1] = 'Cat';
function find_index($searchVal, $arr){
return array_search($searchVal, $arr);
}
print_r(find_index('Cat', $arr['animal']));
Consider this Array,
$arr['animal'][] = 'Dog';
$arr['animal'][] = 'Cat';
$arr['insects'][] = 'Insect1';
$arr['insects'][] = 'Insect2';
Here is Iterator Method,
$search = 'InsectSub1';
$matches = [];
$arr_array = new RecursiveArrayIterator($arr);
$arr_array_iterator = new RecursiveIteratorIterator($arr_array);
foreach($arr_array_iterator as $key => $value)
{
if($value === $search)
{
$fill = [];
$fill['category'] = $arr_array->key();
$fill['key'] = $arr_array_iterator->key();
$fill['value'] = $value;
$matches[] = $fill;
}
}
if($matches)
{
// One or more Match(es) Found
}
else
{
// Not Found
}
$arr['animal'][] = 'Dog';
$arr['animal'][] = 'Cat';
$arr['insects'][] = 'Insect1';
$arr['insects'][] = 'Insect2';
$search_for = 'Cat';
$search_result = [];
while ($part = each($arr)) {
$found = array_search($search_for, $part['value']);
if(is_int($found)) {
$fill = [ 'key1' => $part['key'], 'key2' => $found ];
$search_result[] = $fill;
}
}
echo 'Found '.count($search_result).' result(s)';
print_r($search_result);
I have some data in this format:
even--heaped<br />
even--trees<br />
hardrocks-cocked<br />
pebble-temple<br />
heaped-feast<br />
trees-feast<br />
and I want to end up with an output so that all lines with the same words get added to each other with no repeats.
even--heaped--trees--feast<br />
hardrocks--cocked<br />
pebbles-temple<br />
i tried a loop going through both arrays but its not the exact result I want. for an array $thing:
Array ( [0] => even--heaped [1] => even--trees [2] => hardrocks--cocked [3] => pebbles--temple [4] => heaped--feast [5] => trees--feast )
for ($i=0;$i<count($thing);$i++){
for ($j=$i+1;$j<count($thing);$j++){
$first = explode("--",$thing[$i]);
$second = explode("--",$thing[$j]);
$merge = array_merge($first,$second);
$unique = array_unique($merge);
if (count($unique)==3){
$fix = implode("--",$unique);
$out[$i] = $thing[$i]."--".$thing[$j];
}
}
}
print_r($out);
but the result is:
Array ( [0] => even--heaped--heaped--feast [1] => even--trees--trees--feast [4] => heaped--feast--trees--feast )
which is not what i want. Any suggestions (sorry about the terrible variable names).
This might help you:
$in = array(
"even--heaped",
"even--trees",
"hardrocks--cocked",
"pebbles--temple",
"heaped--feast",
"trees--feast"
);
$clusters = array();
foreach( $in as $item ) {
$words = explode("--", $item);
// check if there exists a word in an existing cluster...
$check = false;
foreach($clusters as $k => $cluster) {
foreach($words as $word) {
if( in_array($word, $cluster) ) {
// add the words to this cluster
$clusters[$k] = array_unique( array_merge($cluster, $words) );
$check = true;
break;
}
}
}
if( !$check ) {
// create a new cluster
$clusters[] = $words;
}
}
// merge back
$out = array();
foreach( $clusters as $cluster ) {
$out[] = implode("--", $cluster);
}
pr($out);
Try this code:
<?php
$data = array ("1--2", "3--1", "4--5", "2--6");
$n = count($data);
$elements = array();
for ($i = 0; $i < $n; ++$i)
{
$split = explode("--", $data[$i]);
$word_num = NULL;
foreach($split as $word_key => $word)
{
foreach($elements as $key => $element)
{
if(isset($element[$word]))
{
$word_num = $key;
unset($split[$word_key]);
}
}
}
if(is_null($word_num))
{
$elements[] = array();
$word_num = count($elements) - 1;
}
foreach($split as $word_key => $word)
{
$elements[$word_num][$word] = 1;
}
}
//combine $elements into words
foreach($elements as $key => $value)
{
$words = array_keys($value);
$elements[$key] = implode("--", $words);
}
var_dump($elements);
It uses $elements as an array of hashes to store the individual unique words as keys. Then combines the keys to create appropriate words.
Prints this:
array(2) {
[0]=>
string(10) "1--2--3--6"
[1]=>
string(4) "4--5"
}
Here is a solution with a simple control flow.
<?php
$things = array('even--heaped', 'even--trees', 'hardrocks--cocked',
'pebble--temple', 'heaped--feast' ,'trees--feast');
foreach($things as $thing) {
$str = explode('--', $thing);
$first = $str[0];
$second = $str[1];
$i = '0';
while(true) {
if(!isset($a[$i])) {
$a[$i] = array();
array_push($a[$i], $first);
array_push($a[$i], $second);
break;
} else if(in_array($first, $a[$i]) && !in_array($second, $a[$i])) {
array_push($a[$i], $second);
break;
} else if(!in_array($first, $a[$i]) && in_array($second, $a[$i])) {
array_push($a[$i], $first);
break;
} else if(in_array($first, $a[$i]) && in_array($second, $a[$i])) {
break;
}
$i++;
}
}
print_r($a);
?>
It seems you have already selected user4035's answer as best.
But i feel this one is optimized(Please correct me if i am wrong): eval.in
Code:
$array = Array ( 'even--heaped' , 'even--trees' ,'hardrocks--cocked' , 'pebbles--temple' , 'heaped--feast' , 'trees--feast' );
print "Input: ";
print_r($array);
for($j=0;$j < count($array);$j++){
$len = count($array);
for($i=$j+1;$i < $len;$i++){
$tmp_array = explode("--", $array[$i]);
$pos1 = strpos($array[$j], $tmp_array[0]);
$pos2 = strpos($array[$j], $tmp_array[1]);
if (!($pos1 === false) && $pos2 === false){
$array[$j] = $array[$j] . '--'.$tmp_array[1];unset($array[$i]);
}elseif(!($pos2 === false) && $pos1 === false){
$array[$j] = $array[$j] . '--'.$tmp_array[0];unset($array[$i]);
}elseif(!($pos2 === false) && !($pos1 === false)){
unset($array[$i]);
}
}
$array = array_values($array);
}
print "\nOutput: ";
print_r($array);