My current code is like :
<?php
$item = "123.456.789.963.852.741";
$item_arr = explode(".", $item);
$inner_count = count($item_arr);
$parent_element = "myarray";
if($inner_count==3){
$my_array[$item_arr[0]]['XYZ-Key'][$item_arr[1]]['XYZ-Key'][$item_arr[2]]['order'] = $count;
$my_array[$parent_element]['XYZ-Key'][$item_arr[1]]['XYZ-Key'][$item_arr[2]]=$my_array[$item_arr[0]]['XYZ-Key'][$item_arr[1]]['XYZ-Key'][$item_arr[2]];
unset($my_array[$item_arr[0]]['XYZ-Key'][$item_arr[1]]['XYZ-Key'][$item_arr[2]]);
}
if($inner_count==4){
$my_array[$item_arr[0]]['XYZ-Key'][$item_arr[1]]['XYZ-Key'][$item_arr[2]]['XYZ-Key'][$item_arr[3]]['order'] = $count;
$my_array[$parent_element]['XYZ-Key'][$item_arr[1]]['XYZ-Key'][$item_arr[2]]['XYZ-Key'][$item_arr[3]]=$my_array[$item_arr[0]]['XYZ-Key'][$item_arr[1]]['XYZ-Key'][$item_arr[2]]['XYZ-Key'][$item_arr[3]];
unset($my_array[$item_arr[0]]['XYZ-Key'][$item_arr[1]]['XYZ-Key'][$item_arr[2]]['XYZ-Key'][$item_arr[3]]);
}
if($inner_count==5){
$my_array[$item_arr[0]]['XYZ-Key'][$item_arr[1]]['XYZ-Key'][$item_arr[2]]['XYZ-Key'][$item_arr[3]]['XYZ-Key'][$item_arr[4]]['order'] = $count;
$my_array[$parent_element]['XYZ-Key'][$item_arr[1]]['XYZ-Key'][$item_arr[2]]['XYZ-Key'][$item_arr[3]]['XYZ-Key'][$item_arr[4]]=$my_array[$item_arr[0]]['XYZ-Key'][$item_arr[1]]['XYZ-Key'][$item_arr[2]]['XYZ-Key'][$item_arr[3]]['XYZ-Key'][$item_arr[4]];
unset($my_array[$item_arr[0]]['XYZ-Key'][$item_arr[1]]['XYZ-Key'][$item_arr[2]]['XYZ-Key'][$item_arr[3]]['XYZ-Key'][$item_arr[4]]);
}
now i want to extend it to more count (right now code is up to 5)
but the problem I can not the code in the same way
You can do it in this manner. Just change string for your format
$item = "1.2.3.4.5";
$ar = explode('.', $item);
$start = '{';
$end = '}';
foreach($ar as $i) {
$start .= '"'.$i.'":{';
$end = '}'.$end;
}
$temp = $start . '"order":{}' .$end; // {"1":{"2":{"3":...{"order":{}}}}}
$res = json_decode($temp,true);
Related
I'm trying to code Conway look-and-say sequence in PHP.
Here is my code:
function look_and_say ($number) {
$arr = str_split($number . " ");
$target = $arr[0];
$count = 0;
$res = "";
foreach($arr as $num){
if($num == $target){
$count++;
}else{
$res .= $count . $target;
$count = 1;
$target = $num;
}
}
return $res;
}
As I run the function, look_and_say(9900) I am getting value I expected: 2920.
My question is for assigning $arr to be $arr = str_split($number) rather than $arr = str_split($number . " "), the result omits the very last element of the $arr and return 29.
Is it normal to add empty space at the end of the $arr foreach to examine the last element or is there any better way to practice this code - besides regex way.
There are 2 methods I was able to come up with.
1 is to add concatenate at the result after the loop too.
function look_and_say ($number) {
$arr = str_split($number);
$target = $arr[0];
$count = 0;
$res = "";
foreach($arr as $num){
if($num == $target){
$count++;
}else{
$res .= $count . $target;
$count = 1;
$target = $num;
}
}
$res .= $count . $target;
return $res;
}
And the 2nd one is to add another if clause inside the loop and determine the last iteration:
function look_and_say ($number) {
$arr = str_split($number);
$target = $arr[0];
$count = 0;
$res = "";
$i=0;
$total = count($arr);
foreach($arr as $num){
if($i == ($total-1))
{
$count++;
$res .= $count . $target;
}
elseif($num == $target){
$count++;
}else{
$res .= $count . $target;
$count = 1;
$target = $num;
}
$i++;
}
return $res;
}
I want to suggest you other way using two nested while loops:
<?php
function lookAndSay($number) {
$digits = str_split($number);
$result = '';
$i = 0;
while ($i < count($digits)) {
$lastDigit = $digits[$i];
$count = 0;
while ($i < count($digits) && $lastDigit === $digits[$i]) {
$i++;
$count++;
}
$result .= $count . $lastDigit;
}
return $result;
}
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>';
I have array with show names like this:
$shows = array('morning_show_15_02_2014_part2.mp3',
'morning_show_15_02_2014_part1.mp3',
'morning_show_14_02_2014_part2.mp3',
'morning_show_14_02_2014_part1.mp3',
'morning_show_13_02_2014_part2.mp3',
'morning_show_13_02_2014_part1.mp3');
So the list look like:
morning_show_15_02_2014_part2.mp3
morning_show_15_02_2014_part1.mp3
morning_show_14_02_2014_part2.mp3
morning_show_14_02_2014_part1.mp3
morning_show_13_02_2014_part2.mp3
morning_show_13_02_2014_part1.mp3
This is what i get when i loop the directory.
But the list should look like this:
morning_show_15_02_2014_part1.mp3
morning_show_15_02_2014_part2.mp3
morning_show_14_02_2014_part1.mp3
morning_show_14_02_2014_part2.mp3
morning_show_13_02_2014_part1.mp3
morning_show_13_02_2014_part2.mp3
Still ordered by date, but part 1 is first and then comes part 2.
How can i get this list into right order?
Thank you for any help!
Resolved!
Code is prett nasty but i got what i was looking for:
public function getMp3ListAsJSONArray() {
$songs = array();
$mp3s = glob($this->files_path . '/*.mp3');
foreach ($mp3s as $key => $mp3Source) {
$mp3Source = basename($mp3Source);
$mp3Title = substr($mp3Source, 4);
$mp3Title = substr($mp3Title, 0, -4);
$mp3Title = basename($mp3Source, ".mp3");
$mp3Title = str_replace('_', ' ', $mp3Title);
$mp3Title = ucfirst($mp3Title);
$songs[$key]['title'] = $mp3Title;
$songs[$key]['mp3'] = urldecode($this->files_url . '/' . $mp3Source);
}
rsort($songs);
$pairCounter = 1;
$counter = 0;
foreach ($songs as $key => $value) {
$playlist[$pairCounter][] = $value;
$counter = $counter + 1;
if($counter == 2) {
$pairCounter = $pairCounter + 1;
$counter = 0;
}
}
foreach ($playlist as $show) {
$finalList[] = $show[1];
$finalList[] = $show[0];
}
$finalList = json_encode($finalList);
return $finalList;
}
Output is like i described in the topic.
Try to use array sort
Here is an example for you
http://techyline.com/php-sorting-array-with-unique-value/
You must definitely write your own string comparision function. Remember that you have 2 different comparisons. The first compares the first parts for the filenames as strings. The second part compares the numbers, where 20 comes after 2. This is a natural number sorting for the second part. The third part is after the last dot in the filename. This will be ignored.
<?php
function value_compare($a, $b) {
$result = 0;
$descending = TRUE;
$positionA = strpos($a, 'part');
$positionB = strpos($b, 'part');
if ($positionA === $positionB) {
$compareFirstPart = substr_compare($a, $b, 0, $positionA + 1);
if ($compareFirstPart === 0) {
$length = 0;
$offset = $positionA + strlen('part');
$positionDotA = strrpos($a, '.');
$positionDotB = strrpos($b, '.');
$part2A = '';
$part2B = '';
if ($positionDotA !== FALSE) {
$part2A = substr($a, $offset, $positionDotA);
} else {
$part2A = substr($a, $offset);
}
if ($positionDotB !== FALSE) {
$part2B = substr($b, $offset, $positionDotB);
} else {
$part2B = substr($b, $offset);
}
$result = strnatcmp($part2A, $part2B);
} else {
$result = $compareFirstPart;
if ($descending) {
$result = -$result;
}
}
}
return $result;
}
$shows = array('morning_show_15_02_2014_part2.mp3', 'morning_show_15_02_2014_part1.mp3', 'morning_show_14_02_2014_part2.mp3', 'morning_show_14_02_2014_part1.mp3', 'morning_show_13_02_2014_part2.mp3', 'morning_show_13_02_2014_part1.mp3');
usort($shows, 'value_compare');
var_dump($shows);
?>
I have an array with a list of domains sorted by domain extensions, like:
values[0] = "programming.ca";
values[1] = "Stackoverflow.ca";
values[2] = "question.com";
values[3] = "answers.com";
values[4] = "AASystems.com";
values[5] = "test.net";
values[6] = "hello.net";
values[7] = "apple.nl";
values[8] = "table.org";
values[9] = "demo.org";
How do I print this array, while automatically grouping it in groups with same domain extension and separated by the line break <br />, so the result will look like this?
programming.ca
Stackoverflow.ca
question.com
answers.com
AASystems.com
test.net
hello.net
apple.nl
table.org
demo.org
Try this.
$ext = "";
for($i = 0; $i < count($values); $i++) {
$parts = explode('.', $values[$i]);
$e = $parts[count($parts) - 1];
if(strcmp($parts[count($parts) - 1], $ext) != 0) {
$ext = $e;
echo '<br/>';
}
echo $values[$i].'<br/>';
}
try this if domain names are in order of domain extensions,
$values[0] = "programming.ca";
$values[1] = "Stackoverflow.ca";
$values[2] = "question.com";
$values[3] = "answers.com";
$values[4] = "AASystems.com";
$values[5] = "test.net";
$values[6] = "hello.net";
$values[7] = "apple.nl";
$values[8] = "table.org";
$values[9] = "demo.org";
$prev_ext = "";
foreach($values as $domain_name)
{
$arr_temp = explode(".", $domain_name);
$domain_ext = $arr_temp[1];
if($prev_ext!=$domain_ext)
{
echo '<br/></br/><br/>';
}
echo $domain_name."<br/>";
$prev_ext = $domain_ext;
}
UPDATE : 2
try this if domain names are not in order of their extensions
$values[0] = "programming.ca";
$values[1] = "AASystems.com";
$values[2] = "demo.org";
$values[3] = "answers.com";
$values[4] = "Stackoverflow.ca";
$values[5] = "test.net";
$values[6] = "hello.net";
$values[7] = "apple.nl";
$values[8] = "table.org";
$values[9] = "question.com";
$arr_domains = array();
foreach($values as $domain_name)
{
$arr_temp = explode(".", $domain_name);
$domain_ext = $arr_temp[1];
$arr_domains[$domain_ext][] = $domain_name;
}
foreach($arr_domains as $ext=>$arr_name)
{
echo "<br/><br/><b>".$ext."</b><br/>";
foreach($arr_name as $name)
{
echo $name."<br/>";
}
}
I edited to hopefully make naming clearer. Basically, explode each domain to get name.extension, then store each name in a dictionary of (extension,domainArray) pairs, then foreach entry in the dictionary, grab the domainArray, then foreach name in the domainArray, echo out the domain name . extension, then a line break, then another line break for every dictionary entry.
<?php
$values[0] = "programming.ca";
$values[1] = "Stackoverflow.ca";
$values[2] = "question.com";
$values[3] = "answers.com";
$values[4] = "AASystems.com";
$values[5] = "test.net";
$values[6] = "hello.net";
$values[7] = "apple.nl";
$values[8] = "table.org";
$values[9] = "demo.org";
$domainsList = [];
foreach ($values as $val) {
$valArr = explode(".", $val);
$name = $valArr[0];
$extension = $valArr[1];
if (isset($domainsList[$extension])) {
$domainsList[$extension][] = $name;
} else {
$domainsList[$extension] = [$name];
}
}
foreach ($domainsList as $extension => $domains) {
foreach ($domains as $domain) {
echo $domain . "." . $extension . "<br />";
}
echo "<br />";
}
Try this code.
$domian = array(
"programming.ca",
"Stackoverflow.ca",
"question.com",
"answers.com",
"AASystems.com",
"test.net",
"hello.net",
"apple.nl",
"table.org",
"demo.org");
$result;
foreach ($domian as $value) {
$arr = explode('.', $value);
$result[$arr[1]][] = $value;
}
print_r($result);
I am trying to save an object with a variable amount of "cols". The number of cols is equal to the number of headers. This is how the code looked before:
if(isset($_POST['submit'])){
$sub = new Sub();
$sub->product_id = $_POST['product_id'];
$sub->col1 = $_POST['col1'];
$sub->col2 = $_POST['col2'];
$sub->col3 = $_POST['col3'];
$sub->col4 = $_POST['col4'];
$sub->col5 = $_POST['col5'];
$sub->col6 = $_POST['col6'];
$sub->col7 = $_POST['col7'];
$sub->col8 = $_POST['col8'];
$sub->col9 = $_POST['col9'];
$sub->col10 = $_POST['col10'];
$sub->col11 = $_POST['col11'];
$sub->col12 = $_POST['col12'];
$sub->col13 = $_POST['col13'];
$sub->col14 = $_POST['col14'];
$sub->col15 = $_POST['col15'];
This is how I want it to look:
if(isset($_POST['submit'])){
$sub = new Sub();
$sub->product_id = $_POST['product_id'];
$i = 0;
foreach($headers as $header){
$i++ ;
$sub->col.$i = $_POST['col'.$i];
}
How do I pass the variable $i into the object's attributes? $sub->(col.$i) ? $sub->(col{$i}) ? Please help me figure this out =) Thank you
Try this:
$sub = new Sub();
$sub->product_id = $_POST['product_id'];
for($i = 1; $i <= count($headers); ++$i)
$sub->{'col' . $i} = $_POST['col' . $i];
But, this is really not the way that the columns should be stored in the Sub object, you should use an array:
$sub->columns = array();
for($i = 1; $i <= count($headers); ++$i) {
$sub->columns[] = $_POST['col' . $i];
}
You have to use {} :
$sub->{'col' . $i} = ...
$field = "col$i";
$sub->$field = "whatver"
I'd prefer a setter method.
class Sub {
public function set($attribute, $value) {
$this->$attribute = $value;
}
}
Now you can do:
foreach($_POST as $key => $value) {
$sub->set($key, $value)
}
Or without the loose coupling:
$i = 1;
while($value = $_POST['col' . $i]) {
$sub->set('col' . $i, $value);
$i++;
}