ruby - 使用 Ruby 替换 YAML 文件中的兄弟值
问题描述
我有一个包含数百家商店的 yaml 文件。这是一个例子:
- store_number: "1"
title_tag: "Title tag for store 1"
meta_description: "Description of store 1"
store_details: "Details of store 1"
find_us:
- store_number: "2"
title_tag: "Title tag for store 2"
meta_description: "Description of store 2"
store_details: "Details of store 2"
find_us:
我需要遍历其中的每一个,比较商店编号,如果匹配,则向find_us
键添加一个值。
我已经能够使用这个搜索文件:
stores_file = YAML.load_file('_data/stores.yml')
stores_file.select do |store|
if store['store_number'] == '1'
puts store
end
end
这按预期打印:
{"store_number"=>"1", "title_tag"=>"Title tag for store 1", "meta_description"=>"Description of store 1", "store_details"=>"Details of store 1", "find_us"=>nil}
我有两个问题,我不知道如何找到兄弟姐妹(find_us
在这种情况下),我不知道如何写入find_us
密钥。
解决方案
Use YAML::Store
With just a little refactoring, you can essentially treat your YAML file as a transactional flat-file database using YAML::Store from the Ruby Standard Library. In order to iterate, though, you will probably need to ensure you have a single root in your YAML data store, rather than an array of hashes as you appear to have now. For example, given:
# _data/stores.yml
---
stores:
- store_number: "1"
title_tag: "Title tag for store 1"
meta_description: "Description of store 1"
store_details: "Details of store 1"
find_us:
- store_number: "2"
title_tag: "Title tag for store 2"
meta_description: "Description of store 2"
store_details: "Details of store 2"
find_us:
require 'yaml/store'
@db = YAML::Store.new '_data/stores.yml'
def update_find_us_for store_number, value
# coerce arguments to String objects
store_number, value = [store_number, value].map &:to_s
# completed transactions write the results back to the
# YAML data store for you
@db.transaction do
@db['stores'].each do |store|
store['find_us'] = value if store['store_number'] == store_number
end
end
end
update_find_us_for 1, 'foo'
Validate Expected Results
Validate in IRB
If you ran the code above in irb, you can validate that you made the changes you expected with pp _.first
, which should print:
{"store_number"=>"1", "title_tag"=>"Title tag for store 1", "meta_description"=>"Description of store 1", "store_details"=>"Details of store 1", "find_us"=>"foo"}
Validate Programmatically
You can get at the changed data through instance variables, too. For example:
@db.instance_variable_get(:@table)['stores'].first.fetch 'find_us'
#=> "foo"
Validate at Shell Prompt
If you'd rather validate the stores.yml file directly, then from the Bash shell:
grep -A4 "store_number: '1'" _data/stores.yml
- store_number: '1' title_tag: Title tag for store 1 meta_description: Description of store 1 store_details: Details of store 1 find_us: foo
推荐阅读
- jquery - 使用 Jquery 将“this”应用于特定父母的其他孩子?
- java - Apache HttpClient v5.0 不在 Windows 上使用 NTLM 进行身份验证
- java - Spring Security - 使用请求主机名进行令牌身份验证
- c# - 找不到为 Main 方法指定的“程序”
- reactjs - 使用域而不是 localhost 启动 React 应用程序
- php - 我如何用 php 选择一个数据?
- java - 在spring boot应用程序中从自己的rest api调用另一个rest api
- javascript - 这里的地图 - 只获取最后一组数据:
- c - 当目标字符串数组太小时,strcat 函数仍然有效
- javascript - TF.js 中两台机器的运行时差异