Javascript按初始位置和对象属性排序

时间:2017-10-04 10:21:29

标签: javascript arrays sorting object properties

我有一个对象数组:

[{
    id : 1,
    tag: "video"
 },
 {
    id : 2,
    tag: "music"
 },
 {
    id : 3,
    tag: "video"
 },
 {
    id : 4,
    tag: "music"
 },
 {
    id : 5,
    tag: "video"
 }]

我想根据2个因素对此数组进行排序:

  1. 元素的初始位置
  2. 标签
  3. 基本上我应该将标签组合在一起,但同时保持添加项目的顺序,输出应如下所示:

    [{
        id : 1,
        tag: "video"
     },
     {
        id : 3,
        tag: "video"
     },
     {
        id : 5,
        tag: "video"
     },
     {
        id : 2,
        tag: "music"
     },
     {
        id : 4,
        tag: "music"
     }]
    

    如您所见,现在它们按标签名称分组,但保留了初始订单。 id = 1的项目位于id = 2的项目之前,因为它是先添加的,依此类推。

    请注意,我不能将id字段用于此类,因为real id不是整数,它是一个无法比较的唯一字符串。所以我应该使用原始位置索引而不是id。

    我唯一看起来不太好的解决方案是制作一大块代码,在初始数组上创建一个for,并通过检查具有相同标签的最后一项来创建一个新项目,将项目置于完美位置在原始数组中添加并抓住它的位置并将其添加到该位置的新数组中。

    对此有什么最佳解决方案吗?感谢

3 个答案:

答案 0 :(得分:1)

您可以按正确的顺序将数组reduce放入子数组中,然后应用Array#concat将其展平:



var data = [{"id":1,"tag":"video"},{"id":2,"tag":"music"},{"id":3,"tag":"video"},{"id":4,"tag":"music"},{"id":5,"tag":"video"}];

var helper = Object.create(null);
var result = [].concat.apply([], data.reduce(function(r, o) {
  var arr;
  
  if(helper[o.tag] === undefined) {
     helper[o.tag] = r.push([]) - 1;
  }
  
  arr = r[helper[o.tag]];
  
  arr.push(o);
  
  return r;
}, []));

console.log(result);




使用Map的ES6解决方案:



const data = [{"id":1,"tag":"video"},{"id":2,"tag":"music"},{"id":3,"tag":"video"},{"id":4,"tag":"music"},{"id":5,"tag":"video"}];

const result = [].concat(...data.reduce((r, o) => {
  const arr = r.get(o.tag) || [];
  arr.push(o);
  return r.set(o.tag, arr);
}, new Map()).values());

console.log(result);




答案 1 :(得分:1)

您可以使用sorting with map和一个对象首次出现标记作为其位置。

  

第一个map

     

生成一个具有索引和位置属性的数组,它反映了第一个按位置排序,第二个按索引排序。

[
    {
        index: 0,
        pos: 0
    },
    {
        index: 1,
        pos: 1
    },
    {
        index: 2,
        pos: 0
    },
    {
        index: 3,
        pos: 1
    },
    {
        index: 4,
        pos: 0
    }
]
     

<强> sort

     

获取对象的position和index属性,并使用它对临时数组进行排序。

     

第二个map

     

获取临时数组并通过从原始数组中获取对象并返回给定索引处的项目来呈现结果。

var data = [{ id : 1, tag: "video" }, { id : 2, tag: "music" }, { id : 3, tag: "video" }, { id : 4, tag: "music" }, { id : 5, tag: "video" }],
    pos = Object.create(null),
    result = data
        .map(function (o, i) {
            (o.tag in pos) || (pos[o.tag] = i);
            return { index: i, pos: pos[o.tag] };
        })
        .sort(function (a, b) {
            return a.pos - b.pos || a.index - b.index;
        })
        .map(function (o) {
            return data[o.index];
        });

console.log(result);

答案 2 :(得分:0)

var arr = [{
    id : 1,
    tag: "video"
 },
 {
    id : 2,
    tag: "music"
 },
 {
    id : 3,
    tag: "video"
 },
 {
    id : 4,
    tag: "music"
 },
 {
    id : 5,
    tag: "video"
 }]


const result = arr
.map((item, i) => ({ index: i, id: item.id, tag:item.tag }))
.sort((a, b) =>  a.tag < b.tag )

console.log(result)