用map, next 和 reject 簡化程式碼(ruby)
阿新 • • 發佈:2019-02-17
For example, we have this Channel class:
class Channel
attr_reader :id, :name
def initialize(id, name)
@id = id
@name = name
end
end
1.
What we have:
One list of objects:
current_channels = [Channel.new(1, 'channel1'), Channel.new(2, 'channel2'), Channel.new(3, 'channel3')]
Task:
1.1 Bad solution
current_channel_ids = []
current_channels.each do |channel|
current_channel_ids << channel.id
end
1.2 Better solution using map
current_channel_ids = current_channels.map { |channel| channel.id }
1.3 Best solution using map
current_channel_ids = current_channels.map(&:id)
2.
What we have:
Two lists of objects:
current_channels = [Channel.new(1, 'channel1'), Channel.new(2, 'channel2'), Channel.new(3, 'channel3')]
need_to_be_assigned_channels = [ Channel.new(1, 'channel1'), Channel.new(4, 'channel4')]
Task:Assign channels in need_to_be_assigned_channels to current_channels array and make sure there're no two channels with identical id.
Solution:
Before each solution, get the an array of ids from current_channels:
current_channel_ids = current_channels.map(&:id)
2.1 Bad solution
need_to_be_assigned_channels.each do |channel|
unless current_channel_ids.include?(channel.id)
current_channels << channel
end
end
2.2 Better solution using next
need_to_be_assigned_channels.each do |channel|
next if current_channel_ids.include?(channel.id)
current_channels << channel
end
2.3 Best solution using reject
current_channels.concat(need_to_be_assigned_channels.reject { |assigned_channel| current_channel_ids.include?(assigned_channel.id) }
3.
What we have:
Two lists of objects:
current_channels = [Channel.new(1, 'channel1'), Channel.new(2, 'channel2'), Channel.new(3, 'channel3')]
need_to_be_deleted_channels = [ Channel.new(1, 'channel1'), Channel.new(3, 'channel3')]
Task:Delete channels from current_channels if the id matches one of the ids in need_to_be_deleted_channels.
Solution:
Before each solution, get the an array of ids from current_channels:
current_channel_ids = current_channels.map(&:id)
3.1 Bad solution
current_channels.each do |channel|
next unless need_to_be_deleted_channel_ids.include?(channel.id)
current_channels.delete(channel)
end
3.2 Best solution using delete_if
current_channels.delete_if { |channel| need_to_be_deleted_channel_ids.include?(channel.id) }