2012-10-30 99 views
2

與另一JSON加盟我有這樣一個JSON:哈希JSON然後在Ruby中

[ 
    { 
    "Low": 8.63, 
    "Volume": 14211900, 
    "Date": "2012-10-26", 
    "High": 8.79, 
    "Close": 8.65, 
    "Adj Close": 8.65, 
    "Open": 8.7 
    }, 
    { 
    "Low": 8.65, 
    "Volume": 12167500, 
    "Date": "2012-10-25", 
    "High": 8.81, 
    "Close": 8.73, 
    "Adj Close": 8.73, 
    "Open": 8.76 
    }, 
    { 
    "Low": 8.68, 
    "Volume": 20239700, 
    "Date": "2012-10-24", 
    "High": 8.92, 
    "Close": 8.7, 
    "Adj Close": 8.7, 
    "Open": 8.85 
    } 
] 

而且已經計算出一個簡單的移動平均收盤價中的每一天,並把它稱爲一個變量​​。我想與原來的JSON加入移動平均值,所以我得到這樣的每一天:

{ 
    "Low": 8.68, 
    "Volume": 20239700, 
    "Date": "2012-10-24", 
    "High": 8.92, 
    "Close": 8.7, 
    "Adj Close": 8.7, 
    "Open": 8.85, 
    "SMA9": 8.92 
    } 

有了我這樣做的sma9day變量:

h = { "SMA9" => sma9day } 
sma9json = h.to_json 
puts sma9json 

其輸出該:

{"SMA9":[8.92,8.93,8.93]} 

我該如何把它與JSON兼容的格式並加入兩個?我需要從上到下進行「匹配/連接」,因爲JSON中的最後8條記錄不會有9天移動平均值(在這些情況下,我仍然喜歡關鍵位置(SMA9),但具有零或零值

謝謝

最新升級。

我現在有這一點,這讓我非常接近,但它返回整個字符串中的SMA9領域的JSON ...

require json 
require simple_statistics 

json = File.read("test.json") 
quotes = JSON.parse(json) 

# Calculations 
def sma9day(quotes, i) 
close = quotes.collect {|quote| quote['Close']} 
sma9day = close.each_cons(9).collect {|close| close.mean} 
end 

quotes = quotes.each_with_index do |day, i| 
    day['SMA9'] = sma9day(quotes, i) 
end 

p quotes[0] 

=> {"Low"=>8.63, "Volume"=>14211900, "Date"=>"2012-10-26", "High"=>8.79, "Close"=>8.65, "Adj Close"=>8.65, "Open"=>8.7, "SMA9"=>[8.922222222222222, 8.93888888888889, 8.934444444444445, 8.94222222222222, 8.934444444444445, 8.937777777777777, 8.95, 8.936666666666667, 8.924444444444443, 8.906666666666666, 8.912222222222221, 8.936666666666666, 8.946666666666665, 8.977777777777778, 8.95111111111111, 8.92, 8.916666666666666]} 

當我嘗試在計算結束前做sma9day.round(2) ,它給出了一個方法錯誤(可能是因爲數組?),並且當我做了sma9day [0] .round(2)時,它確實輪了,但每條記錄當然都有相同的SMA。

任何幫助表示讚賞。謝謝

+0

Thats javascript ... – AJcodez

回答

0

大概是做紅寶石計算,你以某種方式解析了json,並得到了一個紅寶石散列。

爲了得到這個結果,你有一個sma9day值的數組和一個對象數組,並且你想遍歷它們。

要做到這一點,這樣的事情應該讓你開始:

hashes = JSON.parse(json) 
sma9day_values = [9.83, 9.82, etc... ] 

hashes.each_with_index do |hash, index| 
    if index >= 9 
    hash["SMA9"] = sma9day_values[index-9] 
    else 
    hash["SMA9"] = 0 
    end 
end 

puts hashes.to_json 

編輯:

你真的需要嘗試開始紅寶石教程。問題是你正在一個數組上調用round(2)。不使用sma9day(quotes, i)函數中的變量i(提示)。也許嘗試類似sma9day[i].round(2)

另外each_with_index的返回不是要分配的東西。不要這樣做,只需在數組中調用each_with_index即可。即

quotes = quotes.each_with_index do |day, i| #bad 
quotes.each_with_index do |day, i| #good 
+0

嗨AJ,我以爲我評論過這個,抱歉沒有及時回覆。我昨天玩過你的代碼,但無法讓它爲我工作。然後托馬斯貼出來,我一直在試圖弄明白。感謝您的幫助(再次)! – gcubed

+1

嗨AJ - 抱歉遲到的答覆 - 正如你所建議的,我做了一些(更多)紅寶石教程,我很高興地說,一切正常!我一直在四捨五入方面遇到問題,然後意識到這是因爲json結尾處的零值(嘗試四捨五入)。所以我添加了一個if語句,只在該值不爲零時才輪迴。再次感謝所有的幫助! – gcubed

0

我接受了您的輸入並編譯了一個解決方案this gist。我希望它有幫助。

+0

非常感謝托馬斯。我遇到了一個小問題,因爲我計算出的平均數有點不同,你會介意看看上面的更新#2並讓我知道你的想法嗎?再次感謝你的幫助。 PS:我注意到你做了一個sma9.round(3)得到一個有三個整數的數字?有沒有辦法強制兩位小數(如果我不知道有多少數字會在小數前面,但想確保有兩位小數?)。 – gcubed

+0

以下是simple_statistics gem的功能:[源代碼](https://github.com/craigmdavidson/Simple-Statistics/blob/master/lib/simple_statistics.rb)。有許多其他方法可以計算出相同結果的未加權平均值,其中一個顯示在要點中。 –

+0

試着瞭解它是如何工作的。 –