从循环哈希中删除最后一个字符
remove last character from looping Hash
你能帮我用这段代码解决这个问题吗?
total_user_input = []
while true
print "Field Name: "
user_input = gets.chomp
break if user_input.empty?
total_user_input << user_input
end
total_user_input.each do |input|
aa = input.split(":").reduce {|first, second| " \t'#{first}': '#{second}',\r\n".gsub("'",'"') }
puts aa.chomp(',')
end
我得到的结果
"name": "string",
"desc": "string",
"price": "integer",
但我想要的只是删除最后一个逗号
"name": "string",
"desc": "string",
"price": "integer"
谢谢你帮助我
我不知道你的实际情况是什么,但是我根据你的预期,你可以试试。
total_user_input = [
"name:test",
"age:30"
]
input_length = total_user_input.size
total_user_input.each_with_index do |input, index|
aa = input.split(":").reduce {|first, second| " \t'#{first}': '#{second}',\r\n".gsub("'",'"') }
aa = aa.gsub(',', '') if index == input_length - 1 # or aa.slice(-1)
puts aa
end
=> 我的结果
"name": "test",
"age": "30"
TL;DR
我很高兴回答你实际提出的问题,但需要指出的是,你所做的本质上是一种反模式,而不是惯用的Ruby。
我将首先向您展示一种更好的方法来完成您正在做的事情,使用转换阶段而不是单一的惯用方法链。接下来,我将介绍一些替代方案,它们将帮助您处理已经构建的字符串数据。
最后,我还提供了一些您通常应该知道的注意事项,但对于回答您的问题而言并不是必不可少的。它们仍然有用,并且肯定会在您尝试调试某些内容时帮助解决这类问题。
正确的方法
首先,如果可以避免,不要做你正在做的事情。以这种方式解决问题会导致非常脆弱的解决方案。相反,只需将您的输入对直接转换为哈希或 JSON。例如:
require "json"
pp total_user_input
#=> ["name", "string", "desc", "string", "price", "integer"]
aa = total_user_input.each_slice(2).to_h
#=> {"name"=>"string", "desc"=>"string", "price"=>"integer"}
puts JSON.pretty_generate aa
{
"name": "string",
"desc": "string",
"price": "integer"
}
这将分阶段转换您的输入,并将字符串打印到适合写入文件的 STDOUT 或以其他方式漂亮地打印为 JSON。
您的原始问题已得到解答
如果您坚持尝试修改给定的字符串,我们将从将其表示为此处文档开始。
your_pseudo_json = <<~STRING
"name": "string",
"desc": "string",
"price": "integer",
STRING
对于这个给定的字符串,您的选择有限。您还通过使用 Windows 风格的换行符而不是 Unix 风格的换行符使您的生活变得复杂,但是您可以通过以下两种方式之一来处理:
为您的系统使用 $/ record separator,可能是默认定义的,或者您自己设置。然后你可以只使用 String#chomp。例如:
# If you have to set it explicitly, do so by assigning to $/
# NB: You may not. I don't have a Windows system to check.
$/ = "\r\n"
your_pseudo_json.chomp!(",#{$/}")
使用 anchored regular expression 仅删除末尾的项目。无论您平台的行结尾如何,这都将起作用。例如:
your_pseudo_json.sub! /,(?:\r?\n)\z/, ""
如果您是 运行 支持 String#delete_suffix! 的较新 Ruby 那么您几乎可以像 #chomp 一样执行此操作,但使用不带插值的简单字符串.例如:
# for Windows line endings
your_pseudo_json.delete_suffix! ",\r\n"
# for *nix-style line endings
your_pseudo_json.delete_suffix! ",\n"
注意事项
在 Irb 或 Pry 中使用非 Bang 方法进行测试
作为测试说明,在您的 REPL 中使用#chomp、#sub 和#delete_suffix 的非 bang 方法进行测试,这样您就不必在创建字符串时不断重新创建字符串实验。 bang 方法将就地修改您的字符串,除非您 运行 默认启用冻结字符串。
冻结的字符串
此外,请注意,如果您在程序中使用冻结字符串 pragma,例如:
# frozen_string_literal: true
在 .rb 文件的顶部
RUBYOPT="--enable-frozen-string-literal"
在你的环境中调用你的 REPL
然后使用非 bang 方法并将结果分配回不同的(甚至相同的)变量。复制 unfrozen copies of frozen strings 超出了您当前问题的范围,所以我什至根本不会提及它,除非是为了防止其他读者在这个问题上普遍丢掉自行车。 :)
你能帮我用这段代码解决这个问题吗?
total_user_input = []
while true
print "Field Name: "
user_input = gets.chomp
break if user_input.empty?
total_user_input << user_input
end
total_user_input.each do |input|
aa = input.split(":").reduce {|first, second| " \t'#{first}': '#{second}',\r\n".gsub("'",'"') }
puts aa.chomp(',')
end
我得到的结果
"name": "string",
"desc": "string",
"price": "integer",
但我想要的只是删除最后一个逗号
"name": "string",
"desc": "string",
"price": "integer"
谢谢你帮助我
我不知道你的实际情况是什么,但是我根据你的预期,你可以试试。
total_user_input = [
"name:test",
"age:30"
]
input_length = total_user_input.size
total_user_input.each_with_index do |input, index|
aa = input.split(":").reduce {|first, second| " \t'#{first}': '#{second}',\r\n".gsub("'",'"') }
aa = aa.gsub(',', '') if index == input_length - 1 # or aa.slice(-1)
puts aa
end
=> 我的结果
"name": "test",
"age": "30"
TL;DR
我很高兴回答你实际提出的问题,但需要指出的是,你所做的本质上是一种反模式,而不是惯用的Ruby。
我将首先向您展示一种更好的方法来完成您正在做的事情,使用转换阶段而不是单一的惯用方法链。接下来,我将介绍一些替代方案,它们将帮助您处理已经构建的字符串数据。
最后,我还提供了一些您通常应该知道的注意事项,但对于回答您的问题而言并不是必不可少的。它们仍然有用,并且肯定会在您尝试调试某些内容时帮助解决这类问题。
正确的方法
首先,如果可以避免,不要做你正在做的事情。以这种方式解决问题会导致非常脆弱的解决方案。相反,只需将您的输入对直接转换为哈希或 JSON。例如:
require "json"
pp total_user_input
#=> ["name", "string", "desc", "string", "price", "integer"]
aa = total_user_input.each_slice(2).to_h
#=> {"name"=>"string", "desc"=>"string", "price"=>"integer"}
puts JSON.pretty_generate aa
{ "name": "string", "desc": "string", "price": "integer" }
这将分阶段转换您的输入,并将字符串打印到适合写入文件的 STDOUT 或以其他方式漂亮地打印为 JSON。
您的原始问题已得到解答
如果您坚持尝试修改给定的字符串,我们将从将其表示为此处文档开始。
your_pseudo_json = <<~STRING
"name": "string",
"desc": "string",
"price": "integer",
STRING
对于这个给定的字符串,您的选择有限。您还通过使用 Windows 风格的换行符而不是 Unix 风格的换行符使您的生活变得复杂,但是您可以通过以下两种方式之一来处理:
为您的系统使用 $/ record separator,可能是默认定义的,或者您自己设置。然后你可以只使用 String#chomp。例如:
# If you have to set it explicitly, do so by assigning to $/ # NB: You may not. I don't have a Windows system to check. $/ = "\r\n" your_pseudo_json.chomp!(",#{$/}")
使用 anchored regular expression 仅删除末尾的项目。无论您平台的行结尾如何,这都将起作用。例如:
your_pseudo_json.sub! /,(?:\r?\n)\z/, ""
如果您是 运行 支持 String#delete_suffix! 的较新 Ruby 那么您几乎可以像 #chomp 一样执行此操作,但使用不带插值的简单字符串.例如:
# for Windows line endings your_pseudo_json.delete_suffix! ",\r\n" # for *nix-style line endings your_pseudo_json.delete_suffix! ",\n"
注意事项
在 Irb 或 Pry 中使用非 Bang 方法进行测试
作为测试说明,在您的 REPL 中使用#chomp、#sub 和#delete_suffix 的非 bang 方法进行测试,这样您就不必在创建字符串时不断重新创建字符串实验。 bang 方法将就地修改您的字符串,除非您 运行 默认启用冻结字符串。
冻结的字符串
此外,请注意,如果您在程序中使用冻结字符串 pragma,例如:
# frozen_string_literal: true
在 .rb 文件的顶部RUBYOPT="--enable-frozen-string-literal"
在你的环境中调用你的 REPL
然后使用非 bang 方法并将结果分配回不同的(甚至相同的)变量。复制 unfrozen copies of frozen strings 超出了您当前问题的范围,所以我什至根本不会提及它,除非是为了防止其他读者在这个问题上普遍丢掉自行车。 :)