按下一篇文章对文章列表进行排序

时间:2018-07-02 15:09:53

标签: javascript algorithm sorting

我知道有很多与sort相关的问题,但找不到解决方案。

我有这样的数据:

const list = [
  {
    name: 'one',
    next: 'two'
  },
  {
    name: 'three',
    next: 'four'
  },
  {
    name: 'four',
    next: 'five'
  },
  {
    name: 'two',
    next: 'three'
  },
]

我想根据next属性对其进行分类。

我不想按字母顺序排序。但是下一个属性。

如果a.next === b.name,则他排名第一。

我尝试过这个:

list.sort((a, b) => {
 if (a.next === b.name) {
   return -1
 }
})

我该如何实现?

我想要的结果:

list = [
      {
        name: 'one',
        next: 'two'
      },
      {
        name: 'two',
        next: 'three'
      },
      {
        name: 'three',
        next: 'four'
      },
      {
        name: 'four',
        next: 'five'
      }
    ]

2 个答案:

答案 0 :(得分:4)

根据所需的逻辑,假设数组可以可排序。您可以:

您可以使用reduce将数组组织成一个对象。通过检查名称是否不存在来获取第一个元素。使用经典的for来循环数组的长度。

const list = [{"name":"one","next":"two"},{"name":"three","next":"four"},{"name":"four","next":"five"},{"name":"two","next":"three"}];

const order = list.reduce((c, v, i) => Object.assign(c, {[v.name]: v}), {}); //Make an order object. This will make it easier to get the values. Use the name as the key
let key = Object.keys(order).find(o => !list.some(x => x.next === o));  //Find the first element. Element that is not found on next

let result = [];
for (i = 0; i < list.length; i++) {  //Loop thru the array. Get the value from order object. 
  result.push(order[key]);           //Push the array from the object order
  key = order[key].next;             //overide the key with the next
}

console.log(result);

答案 1 :(得分:1)

假设链中没有循环或分叉,则可以使用以下函数在O(n)中对该列表进行不适当的排序:

const list = [
  {
    name: 'one',
    next: 'two'
  },
  {
    name: 'three',
    next: 'four'
  },
  {
    name: 'four',
    next: 'five'
  },
  {
    name: 'two',
    next: 'three'
  }
]

function sortLinkedListBy(list, from, to) {
  // collect list of items into dictionary<name, <next, item>>
  // collect next keys into Set<string>
  const { map, set } = list.reduce(({ map, set }, item) => {
    const { [from]: name, [to]: next } = item
    map.set(name, { next, item })
    set.add(next)
    return { map, set}
  }, { map: new Map(), set: new Set() })
  // locate single name that does not exist in set of next keys
  const [key] = Array.from(map.keys()).filter(key => !set.has(key))
  // reduce list (to iterate same amount of times as number of items)
  // accumulator is a tuplet containing sorted list and next key in chain
  const { list: sorted } = list.reduce(({ list, key: name }) => {
    const { next, item } = map.get(name)
    list.push(item)
    return { list, key: next }
  }, { list: [], key })

  return sorted
}

console.log(sortLinkedListBy(list, 'name', 'next'))