我想知道是否有人可以指出一种更简洁、更好的方法来编写粘贴在此处的代码。该代码从 yelp 中抓取一些数据并将其处理为 json 格式。我不使用 hash.to_json
的原因是因为它会抛出某种堆栈错误,我只能假设是由于散列太大(它不是特别大)。
- 响应对象 = 哈希
- text = 保存到文件的输出
无论如何指导表示赞赏。
def mineLocation
client = Yelp::Client.new
request = Yelp::Review::Request::GeoPoint.new(:latitude=>13.3125,:longitude => -6.2468,:yws_id => 'nicetry')
response = client.search(request)
response['businesses'].length.times do |businessEntry|
text =""
response['businesses'][businessEntry].each { |key, value|
if value.class == Array
value.length.times { |arrayEntry|
text+= "\"#{key}\":["
value[arrayEntry].each { |arrayKey,arrayValue|
text+= "{\"#{arrayKey}\":\"#{arrayValue}\"},"
}
text+="]"
}
else
text+="\"#{arrayKey}\":\"#{arrayValue}\","
end
}
end
end
最佳答案
看起来你所有的代码最终都是这样的:
require 'json'
def mine_location
client = Yelp::Client.new
request = Yelp::Review::Request::GeoPoint.new(latitude: 13.3125,
longitude: -6.2468, yws_id: 'nicetry')
response = client.search(request)
return response['businesses'].to_json
end
这对我来说很好。
如果出于某种原因您确实必须编写自己的 JSON 发射器实现,这里有一些提示。
您在代码中完全忽略的第一件事是 Ruby 是一种面向对象的语言,更具体地说,是一种基于类的面向对象语言。这意味着通过构建一个对象网络来解决问题,这些对象通过消息传递相互通信,并通过执行这些对象所属的类中定义的方法来响应这些消息。
这给了我们很大的力量:动态分派(dispatch)、多态、封装和大量其他。利用这些,您的 JSON 发射器将如下所示:
class Object
def to_json; to_s end
end
class NilClass
def to_json; 'null' end
end
class String
def to_json; %Q'"#{to_s}"' end
end
class Array
def to_json; "[#{map(&:to_json).join(', ')}]" end
end
class Hash
def to_json; "{#{map {|k, v| "#{k.to_json}: #{v.to_json}" }.join(', ')}}" end
end
mine_location
看起来和上面一样,除了明显没有 require 'json'
部分。
如果你想要你的 JSON 格式很好,你可以尝试这样的事情:
class Object
def to_json(*) to_s end
end
class String
def to_json(*) inspect end
end
class Array
def to_json(indent=0)
"[\n#{' ' * indent+=1}#{
map {|el| el.to_json(indent) }.join(", \n#{' ' * indent}")
}\n#{' ' * indent-=1}]"
end
end
class Hash
def to_json(indent=0)
"{\n#{' ' * indent+=1}#{
map {|k, v|
"#{k.to_json(indent)}: #{v.to_json(indent)}"
}.join(", \n#{' ' * indent}")
}\n#{' ' * indent-=1}}"
end
end
实际上这段代码中没有任何特定于 Ruby 的内容。例如,这与任何其他基于类的面向对象语言(例如 Java)中的解决方案看起来完全差不多。这只是面向对象设计 101。
唯一特定于语言的是如何“修改”类并向它们添加方法。在 Ruby 或 Python 中,您实际上只是修改类。在 C# 和 Visual Basic.NET 中,您可能会使用扩展方法,在 Scala 中您会使用隐式转换,在 Java 中可能会使用装饰器设计模式。
您的代码的另一个巨大问题是您试图解决一个显然递归但实际上从未递归的问题。这只是不能工作。您编写的代码基本上是 Fortran-57 代码:没有对象和递归的过程。即使只是从 Fortran 移动一个步骤到,比如说,Pascal,也会给你一个很好的递归过程解决方案:
def jsonify(o)
case o
when Hash
"{#{o.map {|k, v| "#{jsonify(k)}: #{jsonify(v)}" }.join(', ')}}"
when Array
"[#{o.map(&method(:jsonify)).join(', ')}]"
when String
o.inspect
when nil
'null'
else
o.to_s
end
end
当然,你可以在这里用缩进玩同样的游戏:
def jsonify(o, indent=0)
case o
when Hash
"{\n#{' ' * indent+=1}#{
o.map {|k, v|
"#{jsonify(k, indent)}: #{jsonify(v, indent)}"
}.join(", \n#{' ' * indent}") }\n#{' ' * indent-=1}}"
when Array
"[\n#{' ' * indent+=1}#{
o.map {|el| jsonify(el, indent) }.join(", \n#{' ' * indent}") }\n#{' ' * indent-=1}]"
when String
o.inspect
when nil
'null'
else
o.to_s
end
end
这是 puts mine_location
的缩进输出,使用 to_json
的第二个(缩进)版本或 jsonify
的第二个版本生成,没关系,它们都有相同的输出:
[
{
"name": "Nickies",
"mobile_url": "http://mobile.yelp.com/biz/yyqwqfgn1ZmbQYNbl7s5sQ",
"city": "San Francisco",
"address1": "466 Haight St",
"zip": "94117",
"latitude": 37.772201,
"avg_rating": 4.0,
"address2": "",
"country_code": "US",
"country": "USA",
"address3": "",
"photo_url_small": "http://static.px.yelp.com/bpthumb/mPNTiQm5HVqLLcUi8XrDiA/ss",
"url": "http://yelp.com/biz/nickies-san-francisco",
"photo_url": "http://static.px.yelp.com/bpthumb/mPNTiQm5HVqLLcUi8XrDiA/ms",
"rating_img_url_small": "http://static.px.yelp.com/static/20070816/i/ico/stars/stars_small_4.png",
"is_closed": false,
"id": "yyqwqfgn1ZmbQYNbl7s5sQ",
"nearby_url": "http://yelp.com/search?find_loc=466+Haight+St%2C+San+Francisco%2C+CA",
"state_code": "CA",
"reviews": [
{
"rating": 3,
"user_photo_url_small": "http://static.px.yelp.com/upthumb/ZQDXkIwQmgfAcazw8OgK2g/ss",
"url": "http://yelp.com/biz/yyqwqfgn1ZmbQYNbl7s5sQ#hrid:t-sisM24K9GvvYhr-9w1EQ",
"user_url": "http://yelp.com/user_details?userid=XMeRHjiLhA9cv3BsSOazCA",
"user_photo_url": "http://static.px.yelp.com/upthumb/ZQDXkIwQmgfAcazw8OgK2g/ms",
"rating_img_url_small": "http://static.px.yelp.com/static/20070816/i/ico/stars/stars_small_3.png",
"id": "t-sisM24K9GvvYhr-9w1EQ",
"text_excerpt": "So I know gentrification is supposed to be a bad word and all (especially here in SF), but the Lower Haight might benefit a bit from it. At least, I like...",
"user_name": "Trey F.",
"mobile_uri": "http://mobile.yelp.com/biz/yyqwqfgn1ZmbQYNbl7s5sQ?srid=t-sisM24K9GvvYhr-9w1EQ",
"rating_img_url": "http://static.px.yelp.com/static/20070816/i/ico/stars/stars_3.png"
},
{
"rating": 4,
"user_photo_url_small": "http://static.px.yelp.com/upthumb/Ghwoq23_alkaXawgqj7dBA/ss",
"url": "http://yelp.com/biz/yyqwqfgn1ZmbQYNbl7s5sQ#hrid:8xTNOC9L5ZXwGCMNYY-pdQ",
"user_url": "http://yelp.com/user_details?userid=4F2QG3adYIUNXplqqp9ylA",
"user_photo_url": "http://static.px.yelp.com/upthumb/Ghwoq23_alkaXawgqj7dBA/ms",
"rating_img_url_small": "http://static.px.yelp.com/static/20070816/i/ico/stars/stars_small_4.png",
"id": "8xTNOC9L5ZXwGCMNYY-pdQ",
"text_excerpt": "This place was definitely a great place to chill. The atmosphere is very non-threatening and very neighborly. I thought it was cool that they had a girl dj...",
"user_name": "Jessy M.",
"mobile_uri": "http://mobile.yelp.com/biz/yyqwqfgn1ZmbQYNbl7s5sQ?srid=8xTNOC9L5ZXwGCMNYY-pdQ",
"rating_img_url": "http://static.px.yelp.com/static/20070816/i/ico/stars/stars_4.png"
},
{
"rating": 5,
"user_photo_url_small": "http://static.px.yelp.com/upthumb/q0POOE3vv2LzNg1qN8MMyw/ss",
"url": "http://yelp.com/biz/yyqwqfgn1ZmbQYNbl7s5sQ#hrid:pp33WfN_FoKlQKJ-38j_Ag",
"user_url": "http://yelp.com/user_details?userid=FmcKafW272uSWXbUF2rslA",
"user_photo_url": "http://static.px.yelp.com/upthumb/q0POOE3vv2LzNg1qN8MMyw/ms",
"rating_img_url_small": "http://static.px.yelp.com/static/20070816/i/ico/stars/stars_small_5.png",
"id": "pp33WfN_FoKlQKJ-38j_Ag",
"text_excerpt": "Love this place! I've been here twice now and each time has been a great experience. The bartender is so nice. When we had questions about the drinks he...",
"user_name": "Scott M.",
"mobile_uri": "http://mobile.yelp.com/biz/yyqwqfgn1ZmbQYNbl7s5sQ?srid=pp33WfN_FoKlQKJ-38j_Ag",
"rating_img_url": "http://static.px.yelp.com/static/20070816/i/ico/stars/stars_5.png"
}
],
"phone": "4152550300",
"neighborhoods": [
{
"name": "Hayes Valley",
"url": "http://yelp.com/search?find_loc=Hayes+Valley%2C+San+Francisco%2C+CA"
}
],
"rating_img_url": "http://static.px.yelp.com/static/20070816/i/ico/stars/stars_4.png",
"longitude": -122.429926,
"categories": [
{
"name": "Dance Clubs",
"category_filter": "danceclubs",
"search_url": "http://yelp.com/search?find_loc=466+Haight+St%2C+San+Francisco%2C+CA&cflt=danceclubs"
},
{
"name": "Lounges",
"category_filter": "lounges",
"search_url": "http://yelp.com/search?find_loc=466+Haight+St%2C+San+Francisco%2C+CA&cflt=lounges"
},
{
"name": "American (Traditional)",
"category_filter": "tradamerican",
"search_url": "http://yelp.com/search?find_loc=466+Haight+St%2C+San+Francisco%2C+CA&cflt=tradamerican"
}
],
"state": "CA",
"review_count": 32,
"distance": 1.87804019451141
}
]
关于ruby - 我该如何改进?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3015972/