组合数组并保留顺序 - 但优先考虑一个数组的顺序而不是另一个
Posted
技术标签:
【中文标题】组合数组并保留顺序 - 但优先考虑一个数组的顺序而不是另一个【英文标题】:Combine arrays and preserve ordering - but prioritize one array's ordering over another 【发布时间】:2016-08-15 00:41:25 【问题描述】:假设我有两个数组:
Arr1 = ["1-a", "1-b", "1-c"]
Arr2 = ["2-a", "2-b", "2-c"]
我知道如何将它们组合成一个数组,保持它们的顺序:
Arr1.zip(Arr2).flatten(1)
# => ["1-a", "2-a", "1-b", "2-b", "1-c", "2-c"]
在本例中,我认为 Arr1 的“优先级”高于 Arr2,因为“1-a”出现在“2-a”之前,“1-c”出现在“2-c”之前。
如果 Arr2 被“优先化”,会发生以下情况:
Arr2.zip(Arr1).flatten(1)
# => ["2-a", "1-a", "2-b", "1-b", "2-c", "1-c"]
在这些示例中,“优先级”是一种二元状态。但是如果我想使用小数呢?这就是我想要发生的事情:
y axis: percentage of added nodes that are Arr1
x axis: percent completion of Arr2 iteration
100% | X
|
75% | X
|
50% | X
|
25% | X
|
0% | X
-------------------------
0% 25% 50% 75% 100%
【问题讨论】:
【参考方案1】:这是我写的
class Array
# helper method to help with testing
def mean
map(&:to_f).reduce(&:+) / length.to_f
end
# target is another array
# priority is a number between 0 and 1
# if 0, then target will not be merged in at all
# if 1, then the result will be ~50% composed of target
# returns array with the same length as self
# Note that the result will not contain all of self.concat(target)
def priority_merge(priority, target)
# clone the arrays to avoid side-effects
arr1, arr2 = [self, target].map(&:clone)
# get the original length to determine the results length
arr1_len = arr1.length.to_f
# convert priority to float
priority = priority.to_f
# initialize a results set
results = []
# populate the results set
arr1_len.to_i.times do |arr1_idx|
# determine the percentage completed through iteration
pct_iterated = arr1_idx.to_f / arr1_len.to_f
# calculate per-run likelihood of favoring target
per_run_priority = pct_iterated * priority
# conclusively determine which array this iteration will pull from
num_true_cases = (100.0 * per_run_priority).to_i
cases = num_true_cases.times.map true .concat((100 - num_true_cases).times.map false )
priority_run_result = cases.sample
# push from arr2 if the priority run result is true, otherwise push from arr1
elem_to_push = (priority_run_result ? arr2 : arr1).shift
# if arr2 is empty, push from arr1 instead
results << elem_to_push || arr1.shift
end
results
end
end
并测试它
a1 = 50.times.map 1
a2 = 50.times.map 2
puts "MERGE CASE 1"
result = 50.times.map do
result = a1.priority_merge(1.0, a2)
result.select |item| item == 2 .count.to_f / a1.length.to_f
end
puts result.mean
# => is around 50%
puts "MERGE CASE 0.5"
result = 50.times.map do
result = a1.priority_merge(0.5, a2)
result.select |item| item == 2 .count.to_f / a1.length.to_f
end
puts result.mean
# => is around 25%
puts "MERGE CASE 0"
result = 50.times.map do
result = a1.priority_merge(0.0, a2)
result.select |item| item == 2 .count / a1.length.to_f
end
puts result.mean
# => is 0%
【讨论】:
以上是关于组合数组并保留顺序 - 但优先考虑一个数组的顺序而不是另一个的主要内容,如果未能解决你的问题,请参考以下文章