【问题标题】:Finding the direction of Array.sort, with context使用上下文查找 Array.sort 的方向
【发布时间】:2019-05-16 20:11:02
【问题描述】:

我想找到一个项目的方向,给定它的排序值。但是,我发现单独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 已移到它上面。

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

【问题讨论】:

  • “从技术上讲,id 为 t1 的项目已移至索引 1,但不是因为它的 val - 而是因为 t3 已移到它上面”。这不是真的,他们两个都是因为他们的价值观而搬家的,否则,它会一直呆在那里。
  • 我知道这在技术上是不正确的。所有项目都通过 .sort 重新索引。我希望你明白我的意思,尽量不要太挑剔。 ;)
  • 请问您为什么需要这个?
  • @ibrahimmahrir 是正确的。您需要自己编写一个并跟踪事情的进展情况。他将维基百科文章链接到几种不同的排序算法,这些都有伪代码,您可以按照这些伪代码创建自己的。例如:en.wikipedia.org/wiki/Insertion_sort
  • [{a: 5}, {b: 3}, {c: 3}],有人支持c,我们记录到c 的值发生了变化,而ab 保持不变(只是旧数组可以),我们排序,我们得到[{a: 5}, {c: 4}, {b: 3}],我们可以清楚地说c自己移动了,但b没有

标签: javascript arrays sorting mergesort


【解决方案1】:

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

给定一个排序功能,我只想根据它的值确定一个项目是否实际上移动到了不同的索引,而不是因为另一个项目被移动了

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

但是,如果您只是想比较一个项目的结束位置和它的开始位置,您可以这样做。 设置从零到数组长度的范围。然后根据数组的排序顺序对其进行排序。这个排序的范围会告诉你什么时候在哪里被索引。

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)

【讨论】:

    【解决方案2】:

    尽管 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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-27
      • 2016-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-30
      • 2018-01-27
      • 2020-09-21
      相关资源
      最近更新 更多