使用上下文查找Array.sort的方向



我想找到一个项目的方向,给定它的排序值。然而,我发现仅靠index无法实现我想要的。

给定一个排序函数,我只想知道一个项目是否真的根据它的值移动到了不同的索引,而不是因为另一个项目被移动了。

示例:

const things = [
{ id: 't1', val: 4 }, // This moves to index 1, see T1 notes
{ id: 't2', val: 2 },
{ id: 't3', val: 5 }, // This moves to index 0
{ id: 't4', val: 1 },
{ id: 't5', val: 3 },
]
// Sort to highest vals first
let thingOrder = things.sort((a, b) => b.val - a.val)
thingOrder = thingOrder.map((thing, index) => {
const oldIndex = things.indexOf(thing)
if (index === oldIndex)
thing.direction = 'same'
else if (index > oldIndex)
thing.direction = 'up'
else if (index < oldIndex)
thing.direction = 'down'
return thing
})
console.log(thingOrder)

预期结果:

{ id: 't3', val: 5 }, // Up
{ id: 't1', val: 4 }, // Same
{ id: 't5', val: 3 }, // Same
{ id: 't2', val: 2 }, // Down
{ id: 't4', val: 1 }, // Down

T1注意:从技术上讲,id为t1的项目已移动到索引1,但不是因为它是val,而是因为T3已移动到它之上。

我如何才能实现发现一个项目在列表中是否真的向上或向下移动的目标?

根据评论,似乎有一些关于移动意味着什么的讨论。我不确定这意味着什么(即使在评论之后(

给定一个排序函数,我只想知道一个项目是否真的根据它的值移动到了不同的索引,而不是因为另一个项目被移动了

项目不会根据其值进行移动。它的移动是基于其价值与周围人的关系

但是,如果你只想比较一个项目的起点和终点,你可以这样做。设定一个从零到数组长度的范围。然后根据数组的排序顺序对其进行排序。此排序范围将显示索引的位置。

const things = [
{ id: 't1', val: 4 }, // This moves to index 1, see T1 notes
{ id: 't2', val: 2 },
{ id: 't3', val: 5 }, // This moves to index 0
{ id: 't4', val: 1 },
{ id: 't5', val: 3 },
]
// This is a simple range:
let sortOrder = Array.from(things, (_, i) => i)
// Sort it based on things
sortOrder.sort((a, b) => things[a].val - things[b].val )
console.log("sort order:", sortOrder)
// map to direction names
// by comparing index to current position
let directions = sortOrder.map((item, i) => {
if (item > i) return "up"
if (item < i) return "down"
return "same"
})
console.log(directions)

虽然Mark的回答有所帮助,但我并没有完全理解。我想看看一个项目相对于其他项目是向上还是向下移动。

我最终得到的解决方案是:

const things = [
{ id: 't1', val: 4 }, // Expected: Same
{ id: 't2', val: 2 }, // Expected: Down
{ id: 't3', val: 5 }, // Expected: Up
{ id: 't4', val: 1 }, // Expected: Down
{ id: 't5', val: 3 }, // Expected: Same
]
let thingOrder = things.slice().sort((a, b) => b.val - a.val)
indexDiff = (thing, oldIndex) => {
const newIndex = thingOrder.indexOf(thing)
const indexDiff = oldIndex - newIndex
return indexDiff
}
thingOrder = things.map((thing, oldIndex) => { 
const indexDiffVal = indexDiff(thing, oldIndex)
const targetIndexDiff = indexDiff(
thingOrder[oldIndex],
things.indexOf(thingOrder[oldIndex]
))
const moveDistance = indexDiffVal + targetIndexDiff
const moveDirectionSign = Math.sign(moveDistance)
let moveDirection = 
(moveDirectionSign === 1) ? 'up'
: (moveDirectionSign === -1) ? 'down' 
: (moveDirectionSign === 0) ? 'same'
: (moveDirectionSign === -0) ? 'same'
: 'same'
moveDirection = (moveDistance === 1) ? 'same' : moveDirection
thing.direction = moveDirection
return thing
})
console.log(thingOrder)

这些是我在试图找出这个公式时做的笔记。

indexDiff:
t1 = 1i - 2i = -1d (down)
t2 = 2i - 4i = -2d (down)
t3 = 3i - 1i = 2d (up)
t4 = 4i - 5i = -1d (down)
t5 = 5i - 3i = 2d (up)
Compare diffs of item[newIndex] to item[oldIndex]
t1 = oldIndex = 1, t3 = newIndex = 1
t1 = indexDiff(-1), t3 = indexDiff(2)
-1 + 2 = [1] (didn't really move)
t2 = oldIndex = 2, t1 = newIndex = 2
t2 = indexDiff(-2), t1 = indexDiff(-1)
-2 + -1 = [-3] (did move down)
t3 = oldIndex = 3, t5 = newIndex = 3
t3 = indexDiff(2), t5 = indexDiff(2)
2 + 2 = [4] (did move up)
t4 = oldIndex = 4, t2 = newIndex = 4
t4 = indexDiff(-1), t2 = indexDiff(-2)
-1 + -2 = [-3] (did move down)
t5 = oldIndex = 5, t4 = newIndex = 5
t5 = indexDiff(2), t4 = indexDiff(-1)
2 + -1 = [1] (didn't really move)

最新更新