Ответ 1
Вы правы насчет слияния. Merge обновит индекс с текущим значением списка слияния. Так что в вашем случае у вас был
[0] = 1
и объединил его с
[0] = 2
[1] = 3
который закончил переписывание [0]=1
с помощью [0]=2
, а затем установил [1]=3
, в результате получив наблюдаемый массив [2,3]
после слияния.
Очень простой подход к решению этого вопроса заключается в использовании concat
var a = Immutable.List([1]);
var b = Immutable.List([2,3]);
var c = a.concat(b);
И это сработает для этой ситуации. Однако, если ситуация более сложная, это может быть неверно. Например,
var a = Immutable.List([1,4]);
var b = Immutable.List([2,3,4]);
это даст вам два 4, которые больше не являются технически объединением. К сожалению, в Immutable нет союза. Простым способом реализации было бы установить каждое значение в каждом списке как ключ к объекту, а затем взять эти ключи в результате объединения.
function union(left,right){
//object to use for holding keys
var union = {};
//takes the first array and adds its values as keys to the union object
left.forEach(function(x){
union[x] = undefined;
});
//takes the second array and adds its values as keys to the union object
right.forEach(function(x){
union[x] = undefined;
});
//uses the keys of the union object in the constructor of List
//to return the same type we started with
//parseInt is used in map to ensure the value type is retained
//it would be string otherwise
return Immutable.List(Object.keys(union).map(function(i){
return parseInt(i,10);
}));
}
Этот процесс O(2(n+m))
. Любой процесс, который использует contains
или indexOf
, в конечном итоге будет O(n^2)
, поэтому именно здесь были использованы ключи.
позднее редактирование
Hyper-производительный
function union(left,right){
var list = [], screen = {};
for(var i = 0; i < left.length; i++){
if(!screen[left[i]])list.push(i);
screen[left[i]] = 1;
}
for(var i = 0; i < right.length; i++){
if(!screen[right[i]])list.push(i);
screen[right[i]] = 1;
}
return Immutable.List(list);
}