2015年5月2日 星期六

如何將 Javascript 的陣列轉換為 PHP 陣列

昨天在剖析 Yahoo 股市的成交明細下方的量價變化圖時 :

https://tw.stock.yahoo.com/q/ts?s=2412


檢視其原始碼發現, 這張圖的數據來自一組 Javascript 陣列 :


var data=[['99.50', 920],['99.40', 4791],['99.30', 2020],['99.20', 508],['99.10', 246],['99.00', 2645]];

只要以 "var data=" 當頭, 以 ";" 當尾, 掐頭截尾就可以取出 Javascript 的陣列數據了 :

[['99.50', 920],['99.40', 4791],['99.30', 2020],['99.20', 508],['99.10', 246],['99.00', 2645]]

然後用 str_replace() 就可以把框住價格的單引號去除 :

$data=str_replace("'", "", $data);

但是接下來該如何把這個陣列字串轉成 PHP 的陣列進行最大量價的擷取呢? 我參考下面這篇 :

# how to convert javascript array to php array

發現原來用 json_decode() 函式就能辦到了 :

$data=str_replace("'", "", $data);  //去除價格之單引號
var_dump(json_decode($data));

可見這函式並非只能解析 {"a":1, "b":2} 這樣的 JSON 格式, 連 [[1,2],[3,4]] 這樣的二維陣列也是可以的. 解碼後得到的二維陣列如下 :

array(6) { [0]=> array(2) { [0]=> float(99.5) [1]=> int(920) } [1]=> array(2) { [0]=> float(99.4) [1]=> int(4784) } [2]=> array(2) { [0]=> float(99.3) [1]=> int(2019) } [3]=> array(2) { [0]=> float(99.2) [1]=> int(508) } [4]=> array(2) { [0]=> float(99.1) [1]=> int(246) } [5]=> array(2) { [0]=> float(99) [1]=> int(2645) } }

這樣只要對此陣列排序, 就可以在固定位置 (例如第一元素) 取得當日最大量的價格了 (99.4 元, 4784 張).

我參考了下面這三篇文章的作法, 使用 PHP 的 usort() 函式來排序, 將自訂的 mysort() 代入 usort()  中達成倒序排序的目的. 但是要注意, 這三篇都是上升排序 (asc), 我把大於改成小於以得到下降排序 :

# PHP 如何排序二維陣列 [第1維:陣列,第2維:關聯式陣列]
PHP二維陣列排序
玩 PHP : 二維陣列排序

function mysort($a, $b) {
  if($a[1] == $b[1]) return 0;
  return ($a[1] < $b[1]) ? 1 : -1;  //改成小於以便下降排序
  }

$arr=json_decode($data);  //將陣列字串解碼還原為二維陣列
var_dump($arr);  //印出陣列結構
usort($arr,"mysort");  //呼叫 mysort() 作自訂排序
var_dump($arr);  //印出陣列結構

這個 usort() 函式主要是給需要特定比較規則來排序時用的,  當排序成功時傳回 true, 失敗時傳回 false. 其第一個參數是傳入要排序的陣列, 而第二個參數則是一個回呼函式, 此函式須傳回 1, 0, 或 -1, 以便控制元素之前後挪移. 它會被傳入兩個參數, 也就是要被比較的對象, 亦即待排序陣列的行元素. 此處我們想要以第二維為準作下降排序, 所以比較的對象就是 $arr 陣列的第二行元素 $a[1] 與 $b[1]. 當 $a[1] 小於 $b[1] 時傳回 1 往後挪, 最終最大的行元素就會排在最前面, 達成下降排序目的. 參考 :

# http://php.net/manual/en/function.usort.php

原始資料 :

[[99.50, 920],[99.40, 4790],[99.30, 2022],[99.20, 508],[99.10, 246],[99.00, 2645]]

經過下降排序後的結果如下 :

array(6) { [0]=> array(2) { [0]=> float(99.4) [1]=> int(4791) } [1]=> array(2) { [0]=> float(99) [1]=> int(2645) } [2]=> array(2) { [0]=> float(99.3) [1]=> int(2020) } [3]=> array(2) { [0]=> float(99.5) [1]=> int(920) } [4]=> array(2) { [0]=> float(99.2) [1]=> int(508) } [5]=> array(2) { [0]=> float(99.1) [1]=> int(246) } }

這樣固定第一個元素 $arr[0][0]=99.4 就是我要的當日最大量價了.

但很奇怪的是, Yahoo 股市長條圖上 99.4 元最大量顯示的卻是 4791 張, Why? 該不會是 Yahoo 的圖形渲染程式有 Bug 吧?

其他參考 :

# PHP eval(array_as_string) returns null
array_multisort函数的用法


沒有留言 :