I'm using codeigniter for this project;
at the start of my script there's this query that checks the completed steps and sets it into array $completed_steps.
public function checkSteps()
{
$completed_steps = $this->prefModel->checkStepstbl();
$this->getPref($completed_steps);
}
so the example result is like;
Array
(
[01] => Array
(
[cat_id] => 15
[offset] => 4951
)
[02] => Array
(
[cat_id] => 15
[offset] => 4251
)
[03] => Array
(
[cat_id] => 15
[offset] => 4001
)
[04] => Array
(
[cat_id] => 15
[offset] => 4951
)
)
this is my function to get prefectures;
public function getPref($completed_steps)
{
$prefectures = $this->prefModel->getList();
foreach ( $prefectures as $prefecture ) {
$prefectureId = $prefecture["id"];
$batch_count = 0;
$max_batch = 10;
$this->getInd($prefectureId, $completed_steps,$batch_count,$max_batch);
}
}
The $prefectures have;
$prefectures = array(array("id"=>"01","name"=>"北海道"),array("id"=>"02","name"=>"青森県"),array("id"=>"03","name"=>"岩手県"),array("id"=>"04","name"=>"宮城県"),array("id"=>"05","name"=>"秋田県"),array("id"=>"06","name"=>"山形県"),array("id"=>"07","name"=>"福島県"),array("id"=>"08","name"=>"茨城県"),array("id"=>"09","name"=>"栃木県"),array("id"=>"10","name"=>"群馬県"),array("id"=>"11","name"=>"埼玉県"),array("id"=>"12","name"=>"千葉県"),array("id"=>"13","name"=>"東京都"),array("id"=>"14","name"=>"神奈川県"),array("id"=>"15","name"=>"新潟県"),array("id"=>"16","name"=>"富山県"),array("id"=>"17","name"=>"石川県"),array("id"=>"18","name"=>"福井県"),array("id"=>"19","name"=>"山梨県"),array("id"=>"20","name"=>"長野県"),array("id"=>"21","name"=>"岐阜県"),array("id"=>"22","name"=>"静岡県"),array("id"=>"23","name"=>"愛知県"),array("id"=>"24","name"=>"三重県"),array("id"=>"25","name"=>"滋賀県"),array("id"=>"26","name"=>"京都府"),array("id"=>"27","name"=>"大阪府"),array("id"=>"28","name"=>"兵庫県"),array("id"=>"29","name"=>"奈良県"),array("id"=>"30","name"=>"和歌山県"),array("id"=>"31","name"=>"鳥取県"),array("id"=>"32","name"=>"島根県"),array("id"=>"33","name"=>"岡山県"),array("id"=>"34","name"=>"広島県"),array("id"=>"35","name"=>"山口県"),array("id"=>"36","name"=>"徳島県"),array("id"=>"37","name"=>"香川県"),array("id"=>"38","name"=>"愛媛県"),array("id"=>"39","name"=>"高知県"),array("id"=>"40","name"=>"福岡県"),array("id"=>"41","name"=>"佐賀県"),array("id"=>"42","name"=>"長崎県"),array("id"=>"43","name"=>"熊本県"),array("id"=>"44","name"=>"大分県"),array("id"=>"45","name"=>"宮崎県"),array("id"=>"46","name"=>"鹿児島県"),array("id"=>"47","name"=>"沖縄県"));
when getting industry, this is the function;
public function getInd($prefectureId,$completed_steps,$batch_count,$max_batch)
{
$industries = $this->indModel->getList();
foreach ( $industries as $industry ) {
$industryId = $industry["id"];
$this->companiesCount($prefectureId,$industryId,$completed_steps,$batch_count,$max_batch);
}
}
$industries would give;
$industries=array(array("id"=>"1","name"=>"グルメ"),array("id"=>"2","name"=>"住まい"),array("id"=>"3","name"=>"医療・健康・介護"),array("id"=>"4","name"=>"美容・ファッション"),array("id"=>"5","name"=>"暮らし"),array("id"=>"6","name"=>"ショッピング"),array("id"=>"7","name"=>"ペット"),array("id"=>"8","name"=>"旅行宿泊"),array("id"=>"9","name"=>"ビジネス"),array("id"=>"10","name"=>"教育・習い事"),array("id"=>"11","name"=>"趣味"),array("id"=>"12","name"=>"公共機関・団体"),array("id"=>"13","name"=>"レジャー・スポーツ"),array("id"=>"14","name"=>"冠婚葬祭・イベント"),array("id"=>"15","name"=>"自動車・バイク"));
and in my companiesCount function;
public function companiesCount($prefectureId,$industryId, $completed_steps, $batch_count,$max_batch)
{
$loop_flg = true;
$offset = 1;
$limit = 50;
while ($loop_flg) {
if ($completed_steps != null) {
if ((array_key_exists($prefectureId, $completed_steps)) && ($completed_steps[$prefectureId]["cat_id"] == $industryId) && $completed_steps[$prefectureId]["offset"] == $offset) {
continue;
}
}
if($batch_count >= $max_batch){
sleep(75);
$last_offset = $this->lastOffset($prefectureId,$industryId);
$batch_count = $this->batchCount();
if($last_offset == ($offset - $limit)) {
if(!empty($batch_count)) {
$result = $this->indModel->getprocessId();
}
if(!empty($result)) {
if(!($this->PsExists($result->pid))) {
$pid = $this->startCompany($result->prefecture_id,$result->industry_id,$result->offset);
$batch_count++;
$this->compModel->updatePid($result->prefecture_id,$result->industry_id,$pid,$result->offset);
}
}
} else {
return $loop_flg = false;
}
} else {
$pid = $this->startCompany($prefectureId,$industryId,$offset);
$this->compModel->saveStepflg($prefectureId,$industryId,$pid,$offset);
$batch_count++;
$offset += 50;
}
}
}
What I want to do is skip through the array from what is given by the $completed_steps. So that it can start from what remains from the other arrays.
this functionality is located from this code;
if ((array_key_exists($prefectureId, $completed_steps)) && ($completed_steps[$prefectureId]["cat_id"] == $industryId) && $completed_steps[$prefectureId]["offset"] == $offset) {
continue;
}
But I can't do it somehow, help is really needed.
The current results are the perimeter $prefectureId starts again at 01, also the $industryId starts at 1, $offset too will begin from 1.
expected results, based on given $completed_steps;
I want the $prefectureId to set in 05. $industryId starts at 1(because max industry is at 15), offset to start 1 also(because usually offset max is at 4951).
this is my array in print_r()
Array([0]=> stdCLass Object ([name] =>john
[surname] =>future
[group] =>one1
)
[1]=> stdCLass Object ([name] =>chris
[surname] =>past
[group] =>two2
)
)
what I want to do is search this array by group. example. tell it
group ="one1"
and my return would be name=john , surname = future
I don't know how to attempt this.
Assuming the array is called $groups
To return an array containing the name and surname
function get_name_from_groups($groups, $group_name)
{
foreach ( $groups as $group ) {
if ( $group->group == $group_name ) {
return array( 'name' => $group->name,
'surname' => $group->surname
);
}
}
return false;
}
$var = get_name_from_groups($groups, 'one1');
if ( $var === false ) {
echo 'The group one1 does not exist';
exit;
}
echo 'Name = ' . $var['name'];
echo 'Surname = ' . $var['surname'];
To return an object containing the name and surname
function get_name_from_groups($groups, $group_name)
{
foreach ( $groups as $group ) {
if ( $group->group == $group_name ) {
$ret = new stdClass();
$ret->name = $group->name;
$ret->surname = $group->surname;
}
}
return false;
}
$var = get_name_from_groups($groups, 'one1');
if ( $var === false ) {
echo 'The group one1 does not exist';
exit;
}
echo 'Name = ' . $var->name;
echo 'Surname = ' . $var->surname;
I seem to be a little lost on what to so about this, im trying to parse out some info but the stdClass is going to always be changing, so im not too sure on what to do about it and could use come guidance.
//Query
$query = new EntityFieldQuery;
$result = $query
->entityCondition('entity_type', 'taxonomy_term')
->propertyCondition('name', 'GOOG')
->propertyCondition('vid', '3')
->execute();
//This is the output
Array
(
[taxonomy_term] => Array
(
[1868] => stdClass Object
(
[tid] => 1868
)
)
)
Now I can get to the tid by using
$result['taxonomy_term']['1868']->tid
but as mentioned before the the stdClass will be always changing.
You can use recurssive array search like this:
function array_searchRecursive( $needle, $haystack, $strict=false, $path=array() )
{
if( !is_array($haystack) ) {
return false;
}
foreach( $haystack as $key => $val ) {
if( is_array($val) && $subPath = array_searchRecursive($needle, $val, $strict, $path) ) {
$path = array_merge($path, array($key), $subPath);
return $path;
} elseif( (!$strict && $val == $needle) || ($strict && $val === $needle) ) {
$path[] = $key;
return $path;
}
}
return false;
}
Usage:
$arr = (array) $yourObject;
$keypath = array_searchRecursive('tid', $arr);
Example:
$class = new stdClass;
$class->foo = 'foo';
$class->bar = 'bar';
$arr = (array) $class;
$keypath = array_searchRecursive('foo', $arr);
print_r($keypath);
Results:
Array
(
[0] => foo
)
So now to get actual value:
echo $keypath[0]; // foo
I'm trying to parse the following format with PHP:
// This is a comment
{
this is an entry
}
{
this is another entry
}
{
entry
{entry within entry}
{entry within entry}
}
Maybe is just the lack of caffeine, but i can't think of a decent way of getting the contents of the curly braces.
This is quite a common parsing task, basically you need to keep track of the various states you can be in and use a combination of constants and function calls to maintain them.
Here is some rather inelegant code that does just that:
<?php
$input = file_get_contents('input.txt');
define('STATE_CDATA', 0);
define('STATE_COMMENT', 1);
function parseBrace($input, &$i)
{
$parsed = array(
'cdata' => '',
'children' => array()
);
$length = strlen($input);
$state = STATE_CDATA;
for(++$i; $i < $length; ++$i) {
switch($input[$i]) {
case '/':
if ('/' === $input[$i+1]) {
$state = STATE_COMMENT;
++$i;
} if (STATE_CDATA === $state) {
$parsed['cdata'] .= $input[$i];
}
break;
case '{':
if (STATE_CDATA === $state) {
$parsed['children'][] = parseBrace($input, $i);
}
break;
case '}':
if (STATE_CDATA === $state) {
break 2; // for
}
break;
case "\n":
if (STATE_CDATA === $state) {
$parsed['cdata'] .= $input[$i];
}
$state = STATE_CDATA;
break;
default:
if (STATE_CDATA === $state) {
$parsed['cdata'] .= $input[$i];
}
}
}
return $parsed;
}
function parseInput($input)
{
$parsed = array(
'cdata' => '',
'children' => array()
);
$state = STATE_CDATA;
$length = strlen($input);
for($i = 0; $i < $length; ++$i) {
switch($input[$i]) {
case '/':
if ('/' === $input[$i+1]) {
$state = STATE_COMMENT;
++$i;
} if (STATE_CDATA === $state) {
$parsed['cdata'] .= $input[$i];
}
break;
case '{':
if (STATE_CDATA === $state) {
$parsed['children'][] = parseBrace($input, $i);
}
break;
case "\n":
if (STATE_CDATA === $state) {
$parsed['cdata'] .= $input[$i];
}
$state = STATE_CDATA;
break;
default:
if (STATE_CDATA === $state) {
$parsed['cdata'] .= $input[$i];
}
}
}
return $parsed;
}
print_r(parseInput($input));
This produces the following output:
Array
(
[cdata] =>
[children] => Array
(
[0] => Array
(
[cdata] =>
this is an entry
[children] => Array
(
)
)
[1] => Array
(
[cdata] =>
this is another entry
[children] => Array
(
)
)
[2] => Array
(
[cdata] =>
entry
[children] => Array
(
[0] => Array
(
[cdata] => entry within entry
[children] => Array
(
)
)
[1] => Array
(
[cdata] => entry within entry
[children] => Array
(
)
)
)
)
)
)
You'll probably want to clean up all the whitespace but some well placed trim's will sort that for you.
This may not be the best solution for large amount of content, but it works.
<?php
$text = "I am out of the brackets {hi i am in the brackets} Back out { Back in}";
print $text . '<hr />';
$tmp = explode("{",$text);
$tmp2 = array();
$wantedText = array();
for($i = 0; $i < count($tmp); $i++){
if(stristr($tmp[$i],"}")){
$tmp2 = explode("}",$tmp[$i]);
array_push($wantedText,$tmp2[0]);
}
}
print_r($wantedText);
?>
Results:
Array ( [0] => hi i am in the brackets [1] => Back in )
I am working on a front-end web app where a nested unordered list would be used for the jQuery plugin mcdropdown.
Here is the data structure from PHP: a nested array of arrays :
Array
(
[0] => Array
(
[fullpath] => ../foil/alphanumeric/
[depth] => 0
)
[1] => Array
(
[fullpath] => ../foil/alphanumeric/letters/
[depth] => 1
)
[2] => Array
(
[fullpath] => ../foil/alphanumeric/numbers/
[depth] => 1
)
[3] => Array
(
[fullpath] => ../foil/alphanumeric/numbers/symbols/
[depth] => 2
)
)
Basically, I took the excellent answer from this question on SO, modified it a bit :
global $fullpaths; // $fullpaths contains the above data structure in print_r
$result = '';
$currentDepth = -1;
while(!empty($fullpaths))
{
$currentNode = array_shift($fullpaths);
if($currentNode['depth'] > $currentDepth)
{
$result .='<ul>';
}
if($currentNode['depth'] < $currentDepth)
{
$result .=str_repeat('</ul>', $currentDepth - $currentNode['depth']);
}
$result .= '<li>'. $currentNode['fullpath'] .'</li>';
$currentDepth = $currentNode['depth'];
if(empty($fullpaths))
{
$result .= str_repeat('</ul>', 1 + $currentDepth);
}
}
print $result;
and got the following output:
<ul>
<li>../foil/alphanumeric/</li>
<ul>
<li>../foil/alphanumeric/letters/</li>
<li>../foil/alphanumeric/numbers/</li>
<ul>
<li>../foil/alphanumeric/numbers/symbols/</li>
</ul>
</ul>
</ul>
Which cannot be accepted by the mcdropdown jQuery plugin, it expects something like this:
<li rel="1">
'Alphanumeric'
<ul>
<li rel="2">'Letters'</li>
<li rel="3">'Numbers'
<ul>
<li rel="4">'Symbols'</li>
</ul>
</li>
</ul>
</li>
To be frank, I don't quite understand how the answer from that question works, I have been trying to modify that solution to cope with my situation, but still failed.
Any help and suggestion is much appropriated in advance.
If you already have the correct depth values, then you don't need recursion. I have a similar function that I use for <ul>-<li>-generation:
function ulli($newlevel, &$level, $UL="ul", $once=1) {
if ($level == $newlevel) {
echo "</li>\n";
}
while ($level<$newlevel) {
$level++;
echo "\n <$UL>\n";
}
while ($level>$newlevel) {
if ($once-->0) { echo "</li>\n"; }
$level--;
echo " </$UL>"
. ($level>0 ? "</li>" : "") . "\n"; // skip for final </ul> (level=0)
}
}
It needs a current $level variable for reference (=$currentDepth). And you pass it your depth as $newlevel. It however needs the first depth to be 1.
Basic usage is like:
$currentDepth=0;
foreach ($array as $_) {
ulli($_["depth"]+1, $currentDepth);
echo "<li>$_[path]";
}
ulli(0, $currentDepth);
Well, quirky. But it worked for me.
Does this code (indentation apart) produces the result you want?
$d = array(
0 => array(
'fullpath' => '../foil/alphanumeric/',
'depth' => 0
),
1 => array(
'fullpath' => '../foil/alphanumeric/letters/',
'depth' => 1
),
2 => array(
'fullpath' => '../foil/alphanumeric/numbers/',
'depth' => 1
),
3 => array(
'fullpath' => '../foil/alphanumeric/numbers/symbols/',
'depth' => 2
)
);
echo "<ul>\n";
$cdepth = 0; $rel = 1; $first = true; $veryfirst = true;
foreach($d as $e)
{
$mpath = "'" . ucfirst(basename($e['fullpath'])) ."'";
if ( $e['depth'] == $cdepth ) {
if ( $first && !$veryfirst) { echo "</li>\n";}
echo "<li rel=\"$rel\">", $mpath;
$rel++; $first = false; $veryfirst = false;
} else {
$depthdiff = $e['depth'] - $cdepth;
if ( $depthdiff < 0 ) {
for($i = 0; $i < -$depthdiff; $i++) {
echo "</ul>\n</li>\n";
}
} else {
for($i = 0; $i < $depthdiff; $i++) {
echo "\n<ul>\n";
$first = true;
// indeed buggy if $depthdiff > 1...
}
}
echo "<li rel=\"$rel\">", $mpath, "\n";
$rel++; $first = true;
}
$cdepth = $e['depth'];
}
for($i = 0; $i < $cdepth; $i++) {
echo "</ul>\n</li>\n";
}
echo "</ul>\n";
EDITED code: Still not perfect but you can work on it... :D