-2

你能帮我用这段代码解决这个问题吗?

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"

感谢你们对我的帮助

4

2 回答 2

0

我不知道您的实际情况是什么,但我根据您的预期,您可以尝试一下。

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"
于 2021-10-09T13:21:04.880 回答
0

TL;博士

我很高兴回答您实际提出的问题,但需要指出的是,您所做的本质上是一种反模式,而不是惯用的 Ruby。

我将首先向您展示一种更好的方法来做您正在做的事情,使用转换阶段而不是单一的惯用方法链。接下来,我将介绍一些可以帮助您处理已构建的字符串数据的替代方法。

最后,我还提供了一些您通常应该注意的警告,但对于回答您的问题并不是必不可少的。它们仍然很有用,并且在您尝试调试某些东西时肯定会帮助解决这些问题。

正确的方式

首先,如果可以避免的话,不要做你正在做的事情。以这种方式解决问题会导致非常脆弱的解决方案。相反,只需将您的输入对直接转换为 Hash 或 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"
}

这将分阶段转换您的输入,并将字符串打印到适合写入文件或以其他方式漂亮打印为 JSON 的 STDOUT。

您的原始问题已回答

如果您坚持尝试修改给定的字符串,我们将从将其表示为 here-document 开始。

your_pseudo_json = <<~STRING
  "name": "string",
  "desc": "string",
  "price": "integer",
STRING

对于这个给定的字符串,您的选择有限。使用 Windows 样式的换行符而不是 Unix 样式的换行符也会使您的生活复杂化,但您可以通过以下两种方式之一来处理:

  1. 使用系统的$/ 记录分隔符,可能是默认定义的,或者自己设置。然后你可以使用 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!(",#{$/}")
    
  2. 使用锚定正则表达式仅删除末尾的项目。无论您的平台的行尾如何,这都将起作用。例如:

     your_pseudo_json.sub! /,(?:\r?\n)\z/, ""
    
  3. 如果您正在运行支持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 方法将就地修改您的字符串,除非您在默认启用冻结字符串的情况下运行。

冰冻的弦乐

另外,请注意,如果您在程序中使用了 freeze strings pragma,例如:

  • # frozen_string_literal: true在 .rb 文件的顶部
  • RUBYOPT="--enable-frozen-string-literal"调用 REPL 时在您的环境中

然后使用非爆炸方法并将结果分配回不同(甚至相同)的变量。复制冻结字符串的未冻结副本超出了您当前问题的范围,因此我什至根本不会提及它,除非防止其他读者对该主题的一般自行车脱落。:)

于 2021-10-09T17:44:26.397 回答