Как поменять определенные элементы массива местами?
Есть массив обьктов :
arr=[
{
order:1,
name:name,
},
{
order:1,
name:name1,
},
{
order:2,
name:name2,
},{
order:4,
name:name3,
},
{
order:7,
name:name4,
},
order:7,
name:name5,
},
order:8,
name:name6,
},
order:8,
name:name7,
},
order:8,
name:name8,
},
order:9,
name:name9,
},
.......
order:100,
name:name100,
}]
Он выводится в таблицу:
| order | name |
|---|---|
| 1 | name1 |
| 1 | name2 |
| 2 | name3 |
| 4 | name4 |
| 7 | name5 |
| 7 | name6 |
| 8 | name7 |
| 8 | name8 |
| 8 | name9 |
| 9 | name10 |
При клике на строку выделяются элементы, причем элементы с один order выделяются как один обьект. Есть две кнопки: стрелка вниз и вверх, для перемещения соответственно. Если обьект состоит из одного элемента перемещаешь с другим который тоже из одного жлемента состоит понятно все.
А как можно поменять местами если выделенная строка состоит из несколько элементов, жмешь вверху то есть, выбранный должен поменяться местами с вышестоящим и поменять поле order у этих обьектов местами.
То есть жмем на 7 строку(index=6).выделяется сразу три строки - 7,8,9. Жмем на кнопку стрелка вверх. Он должен поменяться местами с предыдущим обьектом, то есть строками 5 и 6. то есть на строке с индексом 4, 5,6 должны стоять name7,name8,name9 и у них у всех в поле order Должны быть 7. А на строках с индексами 7,8 name 5,6 соответственно и в полях в поле order стоять 8.
| order | name |
|---|---|
| 1 | name1 |
| 1 | name2 |
| 2 | name3 |
| 4 | name4 |
| 8 | name7 |
| 8 | name8 |
| 8 | name9 |
| 7 | name5 |
| 7 | name6 |
| 9 | name10 |
Я попробовала вот так
this.mySelectionIndex - массив с индексами выбранных строк. count - число строк обьекта с которым надо поменяться ordClickUp -this.arr[this.mySelectionIndex[0] - 1].order
получается в данной ситуации:
this.mySelectionIndex = [4,5,6];
count=2;
for (let k = 0; k < this.mySelectionIndex.length- 1; k++) {
this.arr[this.mySelectionIndex[k]-count] );
[
this.arr[this.mySelectionIndex[k]],
this.arr[this.mySelectionIndex[k]-count ]
] = [
this.arr[this.mySelectionIndex[k]-count],
this.arr[this.mySelectionIndex[k]]
];
this.arr[this.mySelectionIndex[0] + k].order = ordClickUp;
count--;
}
но результат не тот. в чем ошибка? Получается пока так:
| order | name |
|---|---|
| 1 | name1 |
| 1 | name2 |
| 2 | name3 |
| 4 | name4 |
| 8 | name7 |
| 7 | name5 |
| 8 | name8 |
| 7 | name6 |
| 8 | name9 |
| 9 | name10 |
Ответы (1 шт):
Смена местами двух значений, без создания временной переменной (потому что с переменной - слишком очевидно и скучно):
const arr = [
{ order: 1, name: 'foo' }, // [0]
{ order: 2, name: 'bar' },
{ order: 3, name: 'baz' }, // [2]
];
// для наглядности, здесь я присвою индексы перемещаемых элементов переменным (это не обязательно, конечно же)
let [idxA, idxB] = [0, 2];
// меняем местами элементы массива
arr.splice(idxB, 0, ...arr.splice(idxA, 1, ...arr.splice(idxB, 1)));
// опционально: меняем местами числа в свойстве order (через побитовую операцию XOR)
[idxA, idxB, idxA].forEach(idx => arr[idx].order = arr[idxA].order ^ arr[idxB].order);
console.log(arr);
Вложенное подвыражение arr.splice(idxA, 1, ...arr.splice(idxB, 1)) выполняет перенос элемента с индексом idxB на место элемента с индексом idxA, вернув удаленный элемент (с индексом idxA) обернутый в массив. Затем, этот удаленный элемент добавляется на место перенесенного элемента (то есть, на индекс idxB) внешним подвыражением arr.splice(idxB, 0, ...<результатВложенногоSplice>).
Нюанс: это несколько раз мутирует массив с изменением его длины, т.е. может быть не очень быстрым способом (я не проверял его производительность).
// О методе массива splice можно прочесть на MDN.
Смена местами чисел в свойстве order объектов выполняется последовательным выполнением исключающего ИЛИ. То есть, это по сути
orderA = orderA ^ orderB;
orderB = orderA ^ orderB;
orderA = orderA ^ orderB;
Нюанс: этим способом безопасно менять местами только целые числа со значением по модулю <2млрд., примерно (т.к. побитовые операторы в JS приводят значение своих операндов к 32-битным целым числам).