OK, this seems rather simple and I've looked for another answer, but perhaps I'm not searching for the right thing. I have a list of URLs and pages containing those URLS
https://example.com/?p=1 | https://example.com/go/test404/
https://example.com/?p=1 | https://example.com/404
https://example.com/?p=5 | https://example.com/go/test404/
https://example.com/?p=5 | https://example.com
I loop through each line and parse the URLs into $parent (the first column) and $destination (second column).
Now, I want to end up with the following, but can't figure out how to generate this structure, with the outer array called $allLinks:
Array
(
[https://example.com/go/test404/] => Array
(
[0] => https://example.com/?p=1
[1] => https://example.com/?p=5
)
[https://example.com/404] => Array
(
[0] => https://example.com/?p=1
)
[https://example.com] => Array
(
[0] => https://example.com/?p=5
)
)
Thank you very much for assistance in this.
In a loop, I've tried $allLinks[$destination] .= [$parent] and array_push($allLinks[$destination], $parent) but neither seem to be working for me.
You can do this as you are reading/separating the parts. I don't know how you're doing that, but the below assumes you have read lines from a file into an array. Just use the parent as the key and append [] each destination to the array:
foreach($file as $line) {
list($parent, $destination) = explode(' | ', $line);
$result[$parent][] = $destination;
}
That is how I would do it, but rereading it seems you want the opposite:
foreach($file as $line) {
list($parent, $destination) = explode(' | ', $line);
$result[$destination][] = $parent;
}
array_push requires an array as the first argument, so to use it (not recommended) you'd have to check if it is set and if not then define it as an array first. Something like:
$result[$destination] = $result[$destination] ?? [];
array_push($result[$destination], $parent);
The top line translates into:
if(!isset($result[$destination])) {
$result[$destination] = [];
}
Related
This question already has answers here:
PHP, regex and multi-level dashes and grouping together according to string occurrence
(2 answers)
Closed 4 years ago.
I have to build sitemap.html generator, that creates a tree of URLs.
So for instance if I have those URLs:
https://some.url/with/something/good/ and https://some.url/with/something/bad/
it will create something like this:
- https://some.url/
- https://some.url/with/
- https://some.url/with/something/
- https://some.url/with/something/good/
- https://some.url/with/something/bad/
I have array of every URL from my site, now I was thinking of building multidimensional array.
Example above would be converted to something like this:
$url_structure['https://some.url/']['https://some.url/with/']['https://some.url/with/something/']['https://some.url/with/something/good/'] = 0;
Which will look like this:
Array
(
[https://some.url/] => Array
(
[https://some.url/with/] => Array
(
[https://some.url/with/something/] => Array
(
[https://some.url/with/something/good/] => 0
[https://some.url/with/something/bad/] => 0
)
)
)
)
Have you got an idea how to do that better? That's the only solution I have in mind so far.
Problem is I can't find the way to create something like this, because I don't really know how depth this array will become. I just have array of URLs (around 20k URLs).
Output to sitemap.html is a list that I did above.
You can use a reference variable to do the job in such way
$list = [
'https://some.url/with/something/good/',
'https://some.url/with/something/bad/',
];
$res = [];
foreach ($list as $x) {
// remove root. you can add it after loop.
$x = substr($x, strlen('https://some.url/'));
$path = preg_split('~/+~', trim($x, '/'));
// point to the array
$p = &$res;
foreach($path as $step) {
if(! isset($p[$step])) {
// add next level if it's absent
$p[$step] = [];
}
// go to next level
$p = &$p[$step];
}
}
demo
I have an interesting task which can not handle. I have an PHP array that is generated automatically and randomly once a multi-dimensional, associative or mixed.
$data['sport']['basketball']['team']['player']['position']['hand']['name']['finalelement']
$data['sport']['basketball']['team']['player'][0]['position']['hand']['name']['finalelement']
$data['sport']['basketball']['team']['player'][0]['position']['hand']['name'][0]['finalelement']
$data['sport']['basketball']['team']['player']['position']['hand']['name'][0]['finalelement']
The goal is, no matter whether it is multidimensional or associative get to the final element. There is a simple way that has few if conditions. But I want to ask if you have an idea if there is any more intreresen way?
you may use array_walk_recursive as follows :
$data['sport']['basketball']['team']['player']['position']['hand']['name']['finalelement'] = 'e1';
$data['sport']['basketball']['team']['player'][0]['position']['hand']['name']['finalelement'] = 'e2';
$data['sport']['basketball']['team']['player'][0]['position']['hand']['name'][0]['finalelement'] = 'e3';
$data['sport']['basketball']['team']['player']['position']['hand']['name'][0]['finalelement'] = 'e4';
$list = [];
array_walk_recursive($data, function ($value, $key) use (&$list) {
$list[] = $value;
});
print_r($list);
This will Output the following:
Array (
[0] => e1
[1] => e4
[2] => e2
[3] => e3
)
Next code returns first deepest value that is not an array:
$data['sport']['basketball']['team']['player']['position']['hand']['name'][0]['finalelement'] = 'end';
$current = $data;
while (is_array($current)) {
$current = array_values($current)[0];
}
print $current; // end
I am using an API that returns a CSV string as the following:
Date,Open,High,Low,Close,Volume,Adj Close 2014-06-13,3.10,3.30,3.10,3.30,6638300,3.30
I was wondering if there is an easy way to convert this CSV string to an associative array? I am familiar with working with a CSV file, but not sure what to do with a CSV file string response. I am trying to avoid writing the response to a file, just so I can read it back.
Note, writing this response to a CSV file would result in two rows and seven columns.
If the line terminator is \r\n, then first you need to explode them thru that. Then you can proces from there. Consider this example:
$data = explode("\r\n", $csv_string);
// get the headers first
$headers = array_map('trim', explode(',', array_shift($data)));
$new_data = array();
// get the values and use array combine to use the headers as keys for associative array
foreach($data as $values) {
$pieces = explode(',', $values);
// i just assigned it in an array, since we dont know how many lines of data you will receive
$new_data[] = array_combine($headers, $pieces);
}
$new_data should yield something like this:
Array
(
[0] => Array
(
[Date] => 2014-06-13
[Open] => 3.10
[High] => 3.30
[Low] => 3.10
[Close] => 3.30
[Volume] => 6638300
[Adj Close] => 3.30
)
)
Or just the usual way of handling csv strings. Use str_getcsv().
$data = str_getcsv($csv_string, "\r\n");
$headers = explode(',', array_shift($data));
$data = array_combine($headers, explode(',',reset($data)));
As others have mentioned, str_getcsv() is your friend and is an easy method to convert a CSV string into an array. This function will return an array of results. If you'd like to make it an associative array, use array_combine().
Honestly, though -- str_getcsv() may be overkill. Consider this method using explode():
// so given this string returned by the API
$api_s = "Date,Open,High,Low,Close,Volume,Adj Close\r\n2014-06-13,3.10,3.30,3.10,3.30,6638300,3.30";
// split on carriage return & line feed into two strings
$api_r = explode("\r\n", $api_s);
// split keys and values by comma
$keys = explode(',', $api_r[0]);
$vals = explode(',', $api_r[1]);
// construct associative array
$my_assoc_r = array_combine($keys, $vals);
I am new PHP question and I am trying to create an array from the following string of data I have. I haven't been able to get anything to work yet. Does anyone have any suggestions?
my string:
Acct_Status=active,signup_date=2010-12-27,acct_type=GOLD,profile_range=31-35
I want to dynamically create an array called "My_Data" and have id display something like my following, keeping in mind that my array could return more or less data at different times.
My_Data
(
[Acct_Status] => active
[signup_date] => 2010-12-27
[acct_type] => GOLD
[profile_range] => 31-35
)
First time working with PHP, would anyone have any suggestions on what I need to do or have a simple solution? I have tried using an explode, doing a for each loop, but either I am way off on the way that I need to do it or I am missing something. I am getting something more along the lines of the below result.
Array ( [0] => Acct_Status=active [1] => signup_date=2010-12-27 [2] => acct_type=GOLD [3] => profile_range=31-35} )
You would need to explode() the string on , and then in a foreach loop, explode() again on the = and assign each to the output array.
$string = "Acct_Status=active,signup_date=2010-12-27,acct_type=GOLD,profile_range=31-35";
// Array to hold the final product
$output = array();
// Split the key/value pairs on the commas
$outer = explode(",", $string);
// Loop over them
foreach ($outer as $inner) {
// And split each of the key/value on the =
// I'm partial to doing multi-assignment with list() in situations like this
// but you could also assign this to an array and access as $arr[0], $arr[1]
// for the key/value respectively.
list($key, $value) = explode("=", $inner);
// Then assign it to the $output by $key
$output[$key] = $value;
}
var_dump($output);
array(4) {
["Acct_Status"]=>
string(6) "active"
["signup_date"]=>
string(10) "2010-12-27"
["acct_type"]=>
string(4) "GOLD"
["profile_range"]=>
string(5) "31-35"
}
The lazy option would be using parse_str after converting , into & using strtr:
$str = strtr($str, ",", "&");
parse_str($str, $array);
I would totally use a regex here however, to assert the structure a bit more:
preg_match_all("/(\w+)=([\w-]+)/", $str, $matches);
$array = array_combine($matches[1], $matches[2]);
Which would skip any attributes that aren't made up of letters, numbers or hypens. (The question being if that's a viable constraint for your input of course.)
$myString = 'Acct_Status=active,signup_date=2010-12-27,acct_type=GOLD,profile_range=31-35';
parse_str(str_replace(',', '&', $myString), $myArray);
var_dump($myArray);
Before I write my own function to do it, is there any built-in function, or simple one-liner to convert:
Array
(
[0] => pg_response_type=D
[1] => pg_response_code=U51
[2] => pg_response_description=MERCHANT STATUS
[3] => pg_trace_number=477DD76B-B608-4318-882A-67C051A636A6
)
Into:
Array
(
[pg_response_type] => D
[pg_response_code] =>U51
[pg_response_description] =>MERCHANT STATUS
[pg_trace_number] =>477DD76B-B608-4318-882A-67C051A636A6
)
Just trying to avoid reinventing the wheel. I can always loop through it and use explode.
I can always loop through it and use explode.
that's what you should do.
Edit - didn't read the question right at all, whoops..
A foreach through the array is the quickest way to do this, e.g.
foreach($arr as $key=>$val)
{
$new_vals = explode("=", $val);
$new_arr[$new_vals[0]] = $new_vals[1];
}
This should be around five lines of code. Been a while since I've done PHP but here's some pseudocode
foreach element in the array
explode result on the equals sign, set limit = 2
assign that key/value pair into a new array.
Of course, this breaks on keys that have more than one equals sign, so it's up to you whether you want to allow keys to have equals signs in them.
You could do it like this:
$foo = array(
'pg_response_type=D',
'pg_response_code=U51',
'pg_response_description=MERCHANT STATUS',
'pg_trace_number=477DD76B-B608-4318-882A-67C051A636A6',
);
parse_str(implode('&', $foo), $foo);
var_dump($foo);
Just be sure to encapsulate this code in a function whose name conveys the intent.