PageRenderTime 27ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/lang/ArrayUtil.php

http://rhaco.googlecode.com/
PHP | 380 lines | 148 code | 4 blank | 228 comment | 37 complexity | 677dd973d775a4c0615c6337c66d63df MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. Rhaco::import("lang.Variable");
  3. Rhaco::import("lang.StringUtil");
  4. /**
  5. * ????????????
  6. * @author Kazutaka Tokushima
  7. * @license New BSD License
  8. * @copyright Copyright 2005- rhaco project. All rights reserved.
  9. */
  10. class ArrayUtil{
  11. /**
  12. * ??????????
  13. * @param string $dict
  14. * @param string[] $keys
  15. * @param boolean $fill
  16. * @return hash
  17. */
  18. function dict($dict,$keys,$fill=true){
  19. /***
  20. * $dict = "name=hogehoge,title='rhaco',arg=get\,tha";
  21. * $keys = array("name","arg","description","title");
  22. * $result = ArrayUtil::dict($dict,$keys);
  23. * eq(4,sizeof($result));
  24. * foreach($result as $key => $value) $$key = $value;
  25. * eq("hogehoge",$name);
  26. * eq("rhaco",$title);
  27. * eq(null,$description);
  28. * eq("get,tha",$arg);
  29. *
  30. * $dict = array("hogehoge","rhaco","get,tha");
  31. * $keys = array("name","arg","description","title");
  32. * $result = ArrayUtil::dict($dict,$keys);
  33. * eq(4,sizeof($result));
  34. * foreach($result as $key => $value) $$key = $value;
  35. * eq("hogehoge",$name);
  36. * eq(null,$title);
  37. * eq("get,tha",$description);
  38. * eq("rhaco",$arg);
  39. *
  40. * $dict = array("name=hogehoge,title='rhaco',arg=get\,tha");
  41. * $keys = array("name","arg","description","title");
  42. * $result = ArrayUtil::dict($dict,$keys);
  43. * eq(4,sizeof($result));
  44. * foreach($result as $key => $value) $$key = $value;
  45. * eq("hogehoge",$name);
  46. * eq("rhaco",$title);
  47. * eq(null,$description);
  48. * eq("get,tha",$arg);
  49. *
  50. * $dict = array("id=123,hoge=,abc=abc");
  51. * $result = ArrayUtil::dict($dict,array("id","hoge","abc"));
  52. * eq(123,$result["id"]);
  53. * eq(null,$result["hoge"]);
  54. * eq("abc",$result["abc"]);
  55. */
  56. $result = $args = array();
  57. if(is_array($dict) && sizeof($dict) == 1 && isset($dict[0]) && strpos($dict[0],"=") !== false) $dict = $dict[0];
  58. if(is_array($dict)){
  59. $dict = ArrayUtil::arrays($dict,0,sizeof($keys,true));
  60. foreach($keys as $i => $key){
  61. if($fill){
  62. $result[$key] = array_key_exists($i,$dict) ? $dict[$i] : null;
  63. }else if(array_key_exists($i,$dict)){
  64. $result[$key] = $dict[$i];
  65. }
  66. }
  67. }else{
  68. if(preg_match_all("/.+?[^\\\],|.+?$/",$dict,$match)){
  69. foreach($match[0] as $arg){
  70. list($key,$value) = ArrayUtil::arrays(explode("=",$arg,2),0,2,true);
  71. $value = preg_replace("/^(.*),$/","\\1",$value);
  72. if(StringUtil::isInt($value)){
  73. $args[$key] = intval($value);
  74. }else if(StringUtil::isFloat($value)){
  75. $args[$key] = floatval($value);
  76. }else if($value == ""){
  77. $args[$key] = null;
  78. }else{
  79. $args[$key] = str_replace("\\,",",",preg_replace("/^[\'\"](.*)[\'\"]$/","\\1",$value));
  80. }
  81. }
  82. }
  83. foreach($keys as $name){
  84. if($fill){
  85. $result[$name] = array_key_exists($name,$args) ? $args[$name] : null;
  86. }else if(array_key_exists($name,$args)){
  87. $result[$name] = $args[$name];
  88. }
  89. }
  90. }
  91. return $result;
  92. }
  93. /**
  94. * ?????
  95. * @param mixed $var
  96. * @return boolean
  97. */
  98. function ishash($var){
  99. /***
  100. * assert(!ArrayUtil::ishash(array("A","B","C")));
  101. * assert(!ArrayUtil::ishash(array(0=>"A",1=>"B",2=>"C")));
  102. * assert(ArrayUtil::ishash(array(1=>"A",2=>"B",3=>"C")));
  103. * assert(ArrayUtil::ishash(array("a"=>"A","b"=>"B","c"=>"C")));
  104. * assert(!ArrayUtil::ishash(array("0"=>"A","1"=>"B","2"=>"C")));
  105. * assert(!ArrayUtil::ishash(array(0=>"A",1=>"B","2"=>"C")));
  106. */
  107. if(!is_array($var)) return false;
  108. $keys = array_keys($var);
  109. $size = sizeof($keys);
  110. for($i=0;$i<$size;$i++){
  111. if($keys[$i] !== $i) return true;
  112. }
  113. return false;
  114. }
  115. /**
  116. * ???????????????
  117. * @param mixed[] $array
  118. * @param string $glue
  119. * @param integer $offset
  120. * @param integer $length
  121. * @param boolean $fill
  122. * @return string
  123. */
  124. function implode($array,$glue="",$offset=0,$length=0,$fill=false){
  125. /***
  126. * eq("hogekokepopo",ArrayUtil::implode(array("hoge","koke","popo")));
  127. * eq("koke:popo",ArrayUtil::implode(array("hoge","koke","popo"),":",1));
  128. * eq("koke",ArrayUtil::implode(array("hoge","koke","popo"),":",1,1));
  129. * eq("hoge:koke:popo::",ArrayUtil::implode(array("hoge","koke","popo"),":",0,5,true));
  130. *
  131. */
  132. return implode($glue,ArrayUtil::arrays($array,$offset,$length,$fill));
  133. }
  134. /**
  135. * ?????????case insensitive???????
  136. * @param string $name
  137. * @param array $array
  138. * @return mixed
  139. */
  140. function hget($name,$array){
  141. /***
  142. * $list = array("ABC"=>"AA","deF"=>"BB","gHi"=>"CC");
  143. *
  144. * eq("AA",ArrayUtil::hget("abc",$list));
  145. * eq("BB",ArrayUtil::hget("def",$list));
  146. * eq("CC",ArrayUtil::hget("ghi",$list));
  147. *
  148. * eq(null,ArrayUtil::hget("jkl",$list));
  149. * eq(null,ArrayUtil::hget("jkl","ABCD"));
  150. */
  151. if(!is_array($array)) return null;
  152. $array = array_change_key_case($array);
  153. $name = strtolower($name);
  154. return (array_key_exists($name,$array)) ? $array[$name] : null;
  155. }
  156. /**
  157. * ???????
  158. * @param mixed[] $array
  159. * @param int $low
  160. * @param int $high
  161. * @return mixed[]
  162. */
  163. function arrays($array,$offset=0,$length=0,$fill=false){
  164. /***
  165. * eq(1,sizeof(ArrayUtil::arrays(array(0,1),1,1)));
  166. * eq(2,sizeof(ArrayUtil::arrays(array(0,1,2),0,2)));
  167. * eq(3,sizeof(ArrayUtil::arrays(array(0,1),0,3,true)));
  168. * eq(2,sizeof(ArrayUtil::arrays(array(0,1,2,3,4),3,6)));
  169. * eq(3,sizeof(ArrayUtil::arrays(array(0,1,2,3,4,5,6,7,8,9),3,3)));
  170. * eq(1,sizeof(ArrayUtil::arrays(array(0,1,2,3,4,5,6,7,8,9),3,1)));
  171. * eq(7,sizeof(ArrayUtil::arrays(array(0,1,2,3,4,5,6,7,8,9),3)));
  172. * eq(3,sizeof(ArrayUtil::arrays(array(0,1,2,3,4,5,6,7,8,9),-3,3)));
  173. * eq(1,sizeof(ArrayUtil::arrays(array(0,1,2,3,4,5,6,7,8,9),-3,1)));
  174. * eq(3,sizeof(ArrayUtil::arrays(array(0,1,2,3,4,5,6,7,8,9),-3,5)));
  175. * eq(7,sizeof(ArrayUtil::arrays(array(0,1,2,3,4,5,6,7,8,9),0,-3)));
  176. * eq(1,sizeof(ArrayUtil::arrays(array(0))));
  177. * eq(1,sizeof(ArrayUtil::arrays(array(0),0,-1)));
  178. * eq(2,sizeof(ArrayUtil::arrays(array(0,1,2,3,4,5,6,7,8,9),8,-3)));
  179. *
  180. * eq(array("abc"),ArrayUtil::arrays("abc"));
  181. * eq(array("abc","123"),ArrayUtil::arrays(array("abc","123")));
  182. */
  183. $array = (is_array($array)) ? $array : (is_null($array) ? array() : array($array));
  184. if($offset == 0 && $length == 0) return $array;
  185. $array = (empty($length) || ($length < 0 && (sizeof($array) - ($offset - $length)) <= 0)) ? array_slice($array,$offset) : array_slice($array,$offset,$length);
  186. if($fill) for($i=sizeof($array);$i<$length;$i++) $array[] = null;
  187. return $array;
  188. }
  189. /**
  190. * ???????????????????????
  191. * @param mixed[] $list
  192. * @return mixed[]
  193. */
  194. function lowerflip($list){
  195. /***
  196. * $list = array("abc"=>"hoGe","def"=>123,"ghi"=>"__A__");
  197. * eq(array("hoge"=>"abc",123=>"def","__a__"=>"ghi"),ArrayUtil::lowerflip($list));
  198. */
  199. if(is_array($list)) return array_change_key_case(array_flip($list));
  200. return $list;
  201. }
  202. /**
  203. * $pattern?????????????????????
  204. * @param strin $pattern
  205. * @param string $str
  206. * @return mixed[]
  207. */
  208. function splitkeys($pattern,$str){
  209. /***
  210. * $result = ArrayUtil::splitkeys("/","/abc/def/ghi/jklmn");
  211. * assert(isset($result["abc"]["def"]["ghi"]["jklmn"]));
  212. *
  213. * if(isset($result["abc"]["def"]["ghi"]["jklmn"])){
  214. * eq("/abc/def/ghi/jklmn",$result["abc"]["def"]["ghi"]["jklmn"]);
  215. * }
  216. */
  217. $result = $str;
  218. $list = split($pattern,$str);
  219. rsort($list);
  220. foreach($list as $key){
  221. if($key !== "" && $key !== null) $result = array($key=>$result);
  222. }
  223. return $result;
  224. }
  225. /**
  226. * ?????????????????????
  227. * @param array $list
  228. * @param int $size 0?????????????0????????????
  229. * @return array
  230. */
  231. function rand($list,$size=0){
  232. /***
  233. * $list = array("A"=>123,"B"=>456,"C"=>789);
  234. * $result = ArrayUtil::rand($list,2);
  235. * eq(2,count($result));
  236. *
  237. * foreach($result as $key => $value){
  238. * switch($key){
  239. * case "A": eq(123,$value); break;
  240. * case "B": eq(456,$value); break;
  241. * case "C": eq(789,$value); break;
  242. * default: assert(false,"???????????");
  243. * }
  244. * }
  245. */
  246. $keys = ArrayUtil::arrays(array_rand($list,$size));
  247. if($size <= 0) return $list[$keys[0]];
  248. $result = array();
  249. foreach($keys as $key){
  250. $result[$key] = Variable::copy($list[$key]);
  251. }
  252. return $result;
  253. }
  254. /**
  255. * ????CSV???
  256. * @param array $list
  257. * @param boolean $isheader
  258. * @return string
  259. */
  260. function toCsv($list,$isheader=false){
  261. /***
  262. * $list = array(array(1,2,3,"hoge"),array(4,5,6,"agaga"),array(7,8,9,null));
  263. * $result = "1,2,3,\"hoge\"\n4,5,6,\"agaga\"\n7,8,9,\n";
  264. * eq($result,ArrayUtil::toCsv($list));
  265. *
  266. * $list = array(array("A"=>1,"B"=>2),array("A"=>9,"B"=>8));
  267. * $result = "\"A\",\"B\"\n1,2\n9,8\n";
  268. * eq($result,ArrayUtil::toCsv($list,true));
  269. *
  270. * $list = array(array("A"=>1,"B"=>2),array("A"=>9,"B"=>8,"C"=>7));
  271. * $result = "\"A\",\"B\"\n1,2\n9,8\n";
  272. * eq($result,ArrayUtil::toCsv($list,true));
  273. *
  274. * $list = array(array("A\""=>1,"B"=>2),array("A\""=>9,"B"=>8));
  275. * $result = "\"A\"\"\",\"B\"\n1,2\n9,8\n";
  276. * eq($result,ArrayUtil::toCsv($list,true));
  277. */
  278. $result = "";
  279. if(!empty($list) && is_array($list)){
  280. $head = array();
  281. foreach($list as $values){
  282. foreach(ArrayUtil::arrays($values) as $key => $value) $head[] = $key;
  283. break;
  284. }
  285. $size = sizeof($head);
  286. foreach($list as $values){
  287. $line = "";
  288. $count = 1;
  289. $values = ArrayUtil::arrays($values);
  290. for($i=0;$i<$size;$i++){
  291. $value = (isset($values[$head[$i]])) ? $values[$head[$i]] : null;
  292. $line .= ((is_numeric($value) || empty($value)) ? $value : ("\"".str_replace("\"","\"\"",$value)."\"")).",";
  293. }
  294. $result .= substr($line,0,-1)."\n";
  295. }
  296. if($isheader){
  297. $headline = "";
  298. foreach($head as $value) $headline .= "\"".str_replace("\"","\"\"",$value)."\",";
  299. $result = substr($headline,0,-1)."\n".$result;
  300. }
  301. }
  302. return $result;
  303. }
  304. /**
  305. * CSV?????
  306. * @param string $src
  307. * @param boolean $isheader ????????????
  308. * @return array
  309. */
  310. function parseCsv($src,$isheader=false){
  311. /***
  312. * $src = "1,2,3,\"hoge\"\n4,5,6,\"agaga\"\n";
  313. * $result = array(array(1,2,3,"hoge"),array(4,5,6,"agaga"));
  314. * eq($result,ArrayUtil::parseCsv($src));
  315. *
  316. * $src = "1,2,\"hoge\nhoge\",3\n4,5,\"aga\"\"aga\",6\n";
  317. * $result = array(array(1,2,"hoge\nhoge",3),array(4,5,"aga\"aga",6));
  318. * eq($result,ArrayUtil::parseCsv($src));
  319. *
  320. * $src = <<< __CSV__
  321. * 1,2008/8/8,hoge,,abc
  322. * 2,2006/7/9,hige,ccb,
  323. * 3,,"abc""def",,
  324. * 4,,,"abb,bba",
  325. * __CSV__;
  326. * $result = array(
  327. * array(1,"2008/8/8","hoge",null,"abc"),
  328. * array(2,"2006/7/9","hige","ccb",null),
  329. * array(3,null,"abc\"def",null,null),
  330. * array(4,null,null,"abb,bba",null),
  331. * );
  332. * eq($result,ArrayUtil::parseCsv($src));
  333. *
  334. * $result = array(array("A"=>1,"B"=>2),array("A"=>9,"B"=>8));
  335. * $src = "\"A\",\"B\"\n1,2\n9,8\n";
  336. * eq($result,ArrayUtil::parseCsv($src,true));
  337. *
  338. * $result = array(array("A"=>1,"B"=>2),array("A"=>9,"B"=>8));
  339. * $src = "\"A\",\"B\"\n1,2\n9,8\n";
  340. * eq($result,ArrayUtil::parseCsv($src,true));
  341. *
  342. * $result = array(array("A\""=>1,"B"=>2),array("A\""=>9,"B"=>8));
  343. * $src = "\"A\"\"\",\"B\"\n1,2\n9,8\n";
  344. * eq($result,ArrayUtil::parseCsv($src,true));
  345. */
  346. $result = array();
  347. $head = array();
  348. $src = preg_replace("/\".+?\"/se",
  349. 'str_replace(array(",","\n"),array("RHACO__COMMA","RHACO__ENTER"),"\\0")',
  350. str_replace(array("\"\"","\"\"","\\","\$"),array("RHACO__DOUBLE","RHACO__ESCAPE","RHACO__DOLLAR"),trim(StringUtil::toULD($src)))
  351. );
  352. if($isheader){
  353. list($header,$src) = explode("\n",$src,2);
  354. $head = explode(",",$header);
  355. foreach($head as $key => $value){
  356. $head[$key] = str_replace(array("RHACO__COMMA","RHACO__ENTER","RHACO__DOUBLE","RHACO__ESCAPE","RHACO__DOLLAR"),
  357. array(",","\n","\"","\\","\$"),preg_replace('/^"(.+)"$/',"\\1",$value));
  358. }
  359. }
  360. foreach(explode("\n",$src) as $line){
  361. $list = array();
  362. foreach(explode(",",trim($line)) as $key => $value){
  363. if($value == "RHACO__DOUBLE") $value = null;
  364. $value = ($value == "RHACO__DOUBLE") ? "" :
  365. (str_replace(array("RHACO__COMMA","RHACO__ENTER","RHACO__DOUBLE","RHACO__ESCAPE","RHACO__DOLLAR"),
  366. array(",","\n","\"","\\","\$"),preg_replace('/^"(.+)"$/',"\\1",$value)));
  367. $value = ($value == "") ? null : ((is_numeric($value)) ? ((strpos($value,".") !== false) ? floatval($value) : intval($value)) : $value);
  368. $list[(isset($head[$key]) ? $head[$key] : $key)] = $value;
  369. }
  370. $result[] = $list;
  371. }
  372. return $result;
  373. }
  374. }
  375. ?>