2017-10-04 13 views
0

我有对象的数组:的Javascript排序初始位置和对象属性

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

我想基于2个因素此数组进行排序:

  1. 的元件的初始位置
  2. 标签

基本上我应该将标签组合在一起,但同时保持产品应该看起来像这样:

[{ 
    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字段,因为真正的id不是一个整数,它是一个无法比较的唯一字符串。所以,而不是ID我应该使用原始位置索引。

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

任何最佳解决方案?由于

+0

我重新打开它,因为,它不是按字母顺序排序。它更像是一个分组,然后是一个排序问题。 –

回答

1

可以reduce排列为子阵列以正确的顺序,然后通过应用Array#concat展平,然后:使用Map

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);

而一个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);

+0

由于某些奇怪的原因,stackoverflow片段不能运行代码/显示结果。代码本身起作用。 –

+0

道具的名称并不重要(只要你更新代码),如果它是一个原始类型(字符串,数字等),则内容也不重要。 –

+0

这不是代码中的问题。这是一个在stackoverflow片段沙箱中的问题。如果它在铬控制台中,它在铬中工作:) –

1

您可以使用sorting with map和一个对象来标记其第一次出现的位置。

第一map

生成具有索引和位置poperties阵列,其反射由位置的第一排序和所述第二通过索引。

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

sort

需要的对象的位置和指数属性,并与它的临时数组进行排序。

第二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);

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)