Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Better way to build string

70 views
Skip to first unread message

marcus

unread,
Nov 8, 2005, 1:41:28 PM11/8/05
to
I'm trying to build a query string based on an array of properties. Is
there a shorter/nicer way to do the following?

def build_query_string(properties, prop_type)
result = ""

properties.each do |item|
if prop_type == "tag"
result += " #{item.name}=#{item.value}"
else
if result == ""
result = "?"
else
result += "&"
end
result += "#{item.name}=#{item.value}"
end
end

result
end

/Marcus

Peter Ertl

unread,
Nov 8, 2005, 1:46:01 PM11/8/05
to
I always find it useful to post code that is runnable
by copy+paste so people trying to help me don't have
to implement all the helper stuff first.

> --- Ursprüngliche Nachricht ---
> Von: marcus <m-l...@bristav.se>
> An: ruby...@ruby-lang.org (ruby-talk ML)
> Betreff: Better way to build string
> Datum: Wed, 9 Nov 2005 03:41:28 +0900

Peter Ertl

unread,
Nov 8, 2005, 1:58:55 PM11/8/05
to
def build_query_string(properties, prop_type)
query = properties.map {|p| "#{p.name}=#{p.value}"}
case prop_type
when "tag": (" " + query.join(" "))
else ("?" + query.join("&"))
end
end


> --- Ursprüngliche Nachricht ---
> Von: marcus <m-l...@bristav.se>
> An: ruby...@ruby-lang.org (ruby-talk ML)
> Betreff: Better way to build string
> Datum: Wed, 9 Nov 2005 03:41:28 +0900
>

Eero Saynatkari

unread,
Nov 8, 2005, 2:00:00 PM11/8/05
to

Perhaps you can modify this for your needs:

properties.inject('?') {|memo, (key, value)| memo << "#{key}=#{value}&" }

> /Marcus

E


Eric Schwartz

unread,
Nov 8, 2005, 2:34:47 PM11/8/05
to
Eero Saynatkari <rub...@magical-cat.org> writes:
> Perhaps you can modify this for your needs:
>
> properties.inject('?') {|memo, (key, value)| memo << "#{key}=#{value}&" }

FWIW, I've had a mental block about inject for some time, and this
example very nicely clarified for me what it does and how. Thanks for
the handy example.

Note to OP: Don't forget to use CGI::escape() to properly URL-encode
everything.

-=Eric

Eric Hodel

unread,
Nov 8, 2005, 3:46:31 PM11/8/05
to

"?" + properties.map { |pair| pair.join('=') }.join('&')

Shorter, more expressive, omits the trailing '&'

--
Eric Hodel - drb...@segment7.net - http://segment7.net
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04


Daniel Sheppard

unread,
Nov 8, 2005, 7:47:34 PM11/8/05
to
I'm guessing your code either includes name/value pairs for html/xml tag
attributes or for a query string. I don't see why those two things would
be put in the same function, but if you REALLY want them to spend their
lives together:

return "" if properties.empty?
if prop_type == "tag"
properties.map {|item| " #{item.name}=#{item.value}"}
#or alternatively:
#" " + properties.map {|item|
"#{item.name}=#{item.value}"}.join(" ")
else
"?" properties.map {|item| "#{item.name}=#{item.value}"}
end

If you're using this function for what I think you're using it for...
make sure you escape things properly. For the query strings, use:

require 'uri'
"?" + properties.map {|item| "#{item.name}=#{URI.escape(item.value)}"}

For the attributes, make sure that you escape the values to remove &,"
and ' and any other character that doesn't belong in your encoding. Even
better, use something like Builder if you're building up XML/XHTML.

> -----Original Message-----
> From: marcus [mailto:m-l...@bristav.se]
> Sent: Wednesday, 9 November 2005 5:41 AM
> To: ruby-talk ML
> Subject: Better way to build string
>
> I'm trying to build a query string based on an array of
> properties. Is there a shorter/nicer way to do the following?
>
> def build_query_string(properties, prop_type)
> result = ""
>
> properties.each do |item|
> if prop_type == "tag"
> result += " #{item.name}=#{item.value}"
> else
> if result == ""
> result = "?"
> else
> result += "&"
> end
> result += "#{item.name}=#{item.value}"
> end
> end
>
> result
> end
>

> /Marcus
>
>
>
>
#####################################################################################
This email has been scanned by MailMarshal, an email content filter.
#####################################################################################


marcus

unread,
Nov 9, 2005, 5:56:37 AM11/9/05
to
Thank you everyone. I went with this one as it was the only one who took
everything into account

Peter Ertl wrote:
> def build_query_string(properties, prop_type)
> query = properties.map {|p| "#{p.name}=#{p.value}"}
> case prop_type
> when "tag": (" " + query.join(" "))
> else ("?" + query.join("&"))
> end
> end

/Marcus

0 new messages