从循环哈希中删除最后一个字符

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 风格的换行符使您的生活变得复杂,但是您可以通过以下两种方式之一来处理:

  1. 为您的系统使用 $/ 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!(",#{$/}")
    
  2. 使用 anchored regular expression 仅删除末尾的项目。无论您平台的行结尾如何,这都将起作用。例如:

     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 方法进行测试,这样您就不必在创建字符串时不断重新创建字符串实验。 bang 方法将就地修改您的字符串,除非您 运行 默认启用冻结字符串。

冻结的字符串

此外,请注意,如果您在程序中使用冻结字符串 pragma,例如:

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

然后使用非 bang 方法并将结果分配回不同的(甚至相同的)变量。复制 unfrozen copies of frozen strings 超出了您当前问题的范围,所以我什至根本不会提及它,除非是为了防止其他读者在这个问题上普遍丢掉自行车。 :)