Ruby 如何将哈希数组除最后一个元素外的transaction_date设为nil
问题描述
我有如下由哈希组成的数组:
hash = [{:net_amount=>100.0, :transaction_date=>Sun, 20 Sep 2020, :vat=>0.0}, {:net_amount=>100.0, :transaction_date=>Tue, 20 Oct 2020, :vat=>0.0}, {:net_amount=>100.0, :transaction_date=>Fri, 20 Nov 2020, :vat=>0.0}, {:net_amount=>100.0, :transaction_date=>Sun, 20 Dec 2020, :vat=>0.0}]
我希望将所有元素中除最后一个元素外的transaction_date值替换为nil,期望得到如下结果:
hash = [{:net_amount=>100.0, :transaction_date=>nil, :vat=>0.0}, {:net_amount=>100.0, :transaction_date=>nil, :vat=>0.0}, {:net_amount=>100.0, :transaction_date=>nil, :vat=>0.0}, {:net_amount=>100.0, :transaction_date=>Sun, 20 Dec 2020, :vat=>0.0}]
请问是否存在无需通过each方法遍历的简洁实现方式?
实现方案
1. 无副作用生成新数组(推荐,避免修改原数据)
new_hash = hash[0...-1].map { |h| h.merge(transaction_date: nil) } + [hash.last]
- 用
hash[0...-1]直接切片拿到除最后一个元素外的子数组,无需手动判断索引位置 - 通过
merge生成新的哈希对象,不会修改原数组中的哈希值 - 直接拼接原数组最后一个元素,完全保留其原有
transaction_date值 - 兼容数组仅含1个元素的边界场景:此时
hash[0...-1]为空数组,处理后直接拼接原唯一元素,不会发生修改,符合需求
2. 原地修改原数组(性能更优)
如果需要直接修改原数组对象,可使用:
hash[0...-1].map! { |h| h[:transaction_date] = nil; h }
注:所有Ruby枚举类方法(如
map/map!)底层均基于each实现,这里的写法核心是通过数组切片直接定位修改范围,避免了手动遍历全数组、逐个判断是否为最后一个元素的冗余逻辑,符合简洁实现的需求。
内容的提问来源于stack exchange,提问作者mr_muscle
相关产品推荐
相关产品推荐

