我正在尝试根据选定的ID对选定数量的数组重新排序。例如,我有一个数组:
[ { id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 } ]
,并且选择的ID为1,2,4
。正确的安排应为:
[ { id: 3 }, { id: 1 }, { id: 2 }, { id: 4 }, { id: 5 }]
我设法使安排对一个选定的ID起作用,但是当选择多个ID时,它在不同的测试用例上失败。这些都假定与上面相同的输入。
输入1: [ 1, 2, 4 ]
,移至索引1
:
[ { id: 3 }, { id: 1 }, { id: 2 }, { id: 4 }, { id: 5 } ]
输入2: [ 1, 3, 4 ]
,移至索引1
:
[ { id: 2 }, { id: 1 }, { id: 3 }, { id: 4 }, { id: 5 } ]
输入3: [ 1, 3, 5 ]
,移至索引1
:
[ { id: 2 }, { id: 1 }, { id: 3 }, { id: 5 }, { id: 4 } ]
输入4: [ 1, 2 ]
,移至索引0
或1
:
[ { id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 } ]
输入5: [ 4, 5 ]
,移至索引3
或4
:
[ { id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 } ]
/**
* Function to move array
*/
function array_move(arr, old_index, new_index) {
if (new_index >= arr.length) {
var k = new_index - arr.length + 1;
while (k--) {
arr.push(undefined);
}
}
arr.splice(new_index, 0, arr.splice(old_index, 1)[0]);
};
/**
* Function to find the index
*/
function findWithAttr(array, attr, value) {
for (var i = 0; i < array.length; i += 1) {
if (array[i][attr] === value) {
return i;
}
}
return -1;
}
/**
* Move array to specified position
*/
function moveToSpecifiedInput(selectedImage, iMoveTo) {
selectedImage.reverse();
selectedImage.forEach(function(aData) {
let old_index = findWithAttr(aImageData, 'id', aData);
let new_index = iMoveTo - 1;
array_move(aImageData, old_index, new_index);
});
}
答案 0 :(得分:1)
从数组中删除与ID匹配的元素,并将其放入新数组中。然后将新阵列拼接回原始阵列。
function move_array_elements(array, ids, new_index) {
let extracted = [];
ids.forEach(id => {
let index = array.findIndex(el => el.id == id);
if (index != -1) {
extracted.push(array[index]);
array.splice(index, 1);
}
});
array.splice(new_index, 0, ...extracted);
return array;
}
const orig_array = [ { id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 } ];
console.log(move_array_elements(orig_array, [1, 2, 4], 1));
答案 1 :(得分:1)
通过评论中的澄清,我认为我理解您的问题。这就是我要解决的方法:
function sortArray(array, sortProp, sortValues, sortIndex) {
const elemsBySortVal = array.reduce((obj, elem, idx) => {
obj[elem[sortProp]] = idx;
return obj;
}, {});
let sortedKeys = sortValues.map(val => elemsBySortVal[val]);
let sortedItems = sortedKeys.map(key => array[key]);
let remainingItems = array.filter((_, idx) => !sortedKeys.includes(idx));
return [
...remainingItems.slice(0, sortIndex),
...sortedItems,
...remainingItems.slice(sortIndex),
];
}
console.log(sortArray(
[ { id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 } ],
'id',
[ 1, 2, 4 ],
1,
));
此解决方案分为三个阶段:
这是最复杂的部分。在这里,我们接受您的输入array
并针对输入索引创建一个排序值映射。最好通过示例显示:
输入(array
):
[ { id: 1 }, { id: 3 }, { id: 5 }, { id: 2 }, { id: 4 } ]
输出(elemsBySortVal
):
{
1: 0,
3: 1,
5: 2,
2: 3,
4: 4,
}
现在,我们使用该映射来获取输入数组中作为排序值传递的值的索引:
输入(sortValues
):
[ 1, 2, 4 ]
输出(sortedKeys
):
[ 0, 3, 4 ]
然后将其映射到输入数组中的元素:
输入(sortedKeys
):
[ 0, 3, 4 ]
输出(sortedItems
):
[ { id: 1 }, { id: 2 }, { id: 4 } ]
最后,使用sortedKeys
从输入数组中选择其余项,以排除已经排序的项:
remainingItems
:
[ { id: 3 }, { id: 5 } ]
请注意,即使删除了元素,第2阶段中的所有操作仍保持这些数组的顺序。
现在,我们将输出数组分为3部分:
使用slice
作为切入点,从remainingItems
sortIndex
中切出{@ 1}},排序后的部分只是上一阶段的sortedItems
。
答案 2 :(得分:1)
您可以使用过滤器和接头 请检查评论
let arr=[{id:1}, {id:2}, {id:3}, {id:4}, {id:5}];
let selected=[1,2,4];
let move_2_index=1;
//filter out selected
const selectedonly = arr.filter(a=>selected.includes(a.id));
//filter out not selected
const notselected = arr.filter(a=>!selected.includes(a.id));
//splice to insert selected on not selectd
notselected.splice(move_2_index, 0, selectedonly);
//flattern the array
final_array=notselected.flat();
console.log(final_array);
答案 3 :(得分:1)
null
作为占位符演示中的详细信息。
let arr=[{id:1},{id:2},{id:3},{id:4},{id:5}];
Array.prototype.move = function(to, moveFrom) {
// Make a copy of the original array
let that = [...this];
// Declare an empty array
let moveTo = [];
/*
- Compare current index with the numbers in move array (offset)
- Replace each match with a null as a placeholder so that the
indexes of the array is still accurate.
- Place each match into the empty array from previous step.
*/
that.forEach(function(obj, idx, arr) {
if (moveFrom.indexOf(idx +1) !== -1) {
moveTo.push(arr.splice(idx, 1, null));
}
});
// Remove all nulls
that = that.filter(function(obj) {
return obj !== null;
});
/*
Insert the new moving array into the copied array at the index
indicated in the first parameter.
*/
that.splice(to, 0, moveTo.flat())
return that.flat();
};
console.log(JSON.stringify(arr.move(1, [1, 3, 4])));
console.log(JSON.stringify(arr.move(0, [1, 2, 5])));
console.log(JSON.stringify(arr.move(3, [1, 2, 3])));
console.log(JSON.stringify(arr.move(1, [2, 5])));
console.log(JSON.stringify(arr.move(2, [1, 4])));