如何根据其他标签数组对带有标签的对象数组进行排序? [英] How to sort an array of objects with labels according to other array of labels?

查看:64
本文介绍了如何根据其他标签数组对带有标签的对象数组进行排序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

例如,我想对带有标签的对象数组进行排序

I want to sort an array of objects with labels, for example

var arrayToBeSorted = [{label: 'firstLabel', value: 123}, {label: 'secondLabel', value: 456}, {label: 'thirdLabel', value: 789}]

例如,

和一组标签作为基线

and an array of labels as a baseline, for example

var labels = ['secondLabel', 'thirdLabel', 'fourthLabel', 'firstLabel']

现在,我想对第一个数组进行排序,以使其中的对象遵循第二个数组labels中标签的顺序.

Now I want to sort my first array, so that the objects in it follow the order of labels in the second array labels.

我知道带有自定义比较器之类的基本排序机制

I know basic sorting mechanism with custom comparators like

CustomComparator: function(a, b) {
  if (a[0].length > b[0].length) return -1;
  if (a[0].length < b[0].length) return 1;
  return 0;
}

但是我不知道如何转换它.

but I have no idea on how to convert this.

在我的研究中,我发现了 用ruby编码的stackoverflow解决方案,但我不知道javascript中是否有类似的选项.

In my research I found this solution on stackoverflow coded in ruby, but I don't know if there is a similar option in javascript.

感谢您的帮助,为此投入了很多时间.

I appreciate any help, invested quite some time on this.

推荐答案

有两种方法:

  1. 使用indexOf重复搜索labels数组

使用地图,这样可以更快地查找标签索引

Using a map so looking up the index of a label is quicker

以下是使用indexOf的示例(在ES2015 +中):

Here's an example using indexOf (in ES2015+):

arrayToBeSorted.sort((a, b) => labels.indexOf(a.label) - labels.indexOf(b.label));

实时复制:

var arrayToBeSorted = [{label: 'firstLabel', value: 123}, {label: 'secondLabel', value: 456}, {label: 'thirdLabel', value: 789}];

var labels = ['secondLabel', 'thirdLabel', 'fourthLabel', 'firstLabel'];

arrayToBeSorted.sort((a, b) => labels.indexOf(a.label) - labels.indexOf(b.label));

console.log(arrayToBeSorted);

请注意,如果labels中不存在标签,则indexOf将返回-1,这将使未知标签出现在结果的开头.如果您想在末尾使用它们,请检查-1并将其替换为Infinity.

Note that indexOf will return -1 if the label doesn't exist in labels, which will make unknown labels appear at the beginning of the result. If you want them at the end instead, check for -1 and replace it with Infinity.

这是一个使用地图加快查找那些索引的示例(在ES2015 +中):

Here's an example using a map to speed up finding those indexes (in ES2015+):

const map = new Map(labels.map((label, index) => [label, index]));
arrayToBeSorted.sort((a, b) => {
    let aindex = map.get(a.label);
    if (aindex === null) {
        aindex = -1; // Or Infinity if you want them at the end
    }
    let bindex = map.get(b.label);
    if (bindex === null) {
        bindex = -1; // ""
    }
    return aindex - bindex;
});

实时复制:

var arrayToBeSorted = [{label: 'firstLabel', value: 123}, {label: 'secondLabel', value: 456}, {label: 'thirdLabel', value: 789}];

var labels = ['secondLabel', 'thirdLabel', 'fourthLabel', 'firstLabel'];

const map = new Map(labels.map((label, index) => [label, index]));
arrayToBeSorted.sort((a, b) => {
    let aindex = map.get(a.label);
    if (aindex === null) {
        aindex = -1; // Or Infinity if you want them at the end
    }
    let bindex = map.get(b.label);
    if (bindex === null) {
        bindex = -1; // ""
    }
    return aindex - bindex;
});

console.log(arrayToBeSorted);

这样做是为了清楚起见,并避免在回调中多次查找标签.在地图中进行第二次标签查找会更加简洁:

That's written for clarity and to avoid looking up the labels more than once in the callback. It can be more concise at the cost of a second label lookup in the map:

const map = new Map(labels.map((label, index) => [label, index]));
arrayToBeSorted.sort((a, b) => {
    const aindex = map.has(a.label) ? map.get(a.label) : -1; // Or Infinity if you want them at the end
    const bindex = map.has(b.label) ? map.get(b.label) : -1; // "
    return aindex - bindex;
});

实时复制:

var arrayToBeSorted = [{label: 'firstLabel', value: 123}, {label: 'secondLabel', value: 456}, {label: 'thirdLabel', value: 789}];

var labels = ['secondLabel', 'thirdLabel', 'fourthLabel', 'firstLabel'];

const map = new Map(labels.map((label, index) => [label, index]));
arrayToBeSorted.sort((a, b) => {
    const aindex = map.has(a.label) ? map.get(a.label) : -1; // Or Infinity if you want them at the end
    const bindex = map.has(b.label) ? map.get(b.label) : -1; // "
    return aindex - bindex;
});

console.log(arrayToBeSorted);

甚至可以是:

const map = new Map(labels.map((label, index) => [label, index]));
arrayToBeSorted.sort((a, b) =>
    (map.has(a.label) ? map.get(a.label) : -1) - (map.has(b.label) ? map.get(b.label) : -1)
);

...但是对我来说,这在调试等方面使生活变得太困难了.

...but for me that's making life too difficult when debugging, etc.

这篇关于如何根据其他标签数组对带有标签的对象数组进行排序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆