如何通过2个属性对数组进行排序? (正则表达式)

时间:2022-04-22 07:14:32

I have an array that has items like so:

我有一个像这样的项目的数组:

var myArray =
 [
 {catNum : 'CAT I #4', trackingNumber : 'ORG Cat-123'},
 {catNum : 'CAT I #6', trackingNumber : 'ORG Dog-345'},
 {catNum : 'CAT I #2', trackingNumber : 'ORG Cat-123'},
 {catNum : 'CAT I #2', trackingNumber : 'ORG Cat-345'},
 {catNum : 'CAT II #15', trackingNumber : 'ORG Fish-264'},
 {catNum : 'CAT III #1', trackingNumber : 'ORG Bird-123'},
 {catNum : 'CAT II #7', trackingNumber : 'ORG Dog-533'},
 ]

I want to sort the array by catNum and if the catNum is identical, then sort by the tracking number.

我想通过catNum对数组进行排序,如果catNum相同,则按跟踪号排序。

In the following code, I was able to sort by the first property (ie: CATI # --> CAT II # --> CAT III #):

在下面的代码中,我能够按第一个属性排序(即:CATI# - > CAT II# - > CAT III#):

myArray.sort(function mySort(a, b)
                {
                    return catTrackSort(a, b);
                });

 function catTrackSort(a, b)
        {
            var left = a.catNum.match(/CAT ([IV]+) #([0-9]+)/);
            var right = b.catNum.match(/CAT ([IV]+) #([0-9]+)/);

            if (left[1].length === right[1].length)
            {
                return left[2] - right[2];
            }
            else
            {
                return left[1].length - right[1].length;
            }
        }

In the compare function, if catNum is identical, I want to sort by alphabetical order on the trackingNumber property-- I have tried the following, but it doesn't sort:

在比较函数中,如果catNum是相同的,我想在trackingNumber属性上按字母顺序排序 - 我尝试了以下内容,但它没有排序:

function catTrackSort(a, b)
        {
            var left = a.catNum.match(/CAT ([IV]+) #([0-9]+)/);
            var right = b.catNum.match(/CAT ([IV]+) #([0-9]+)/);

            if (left[1].length === right[1].length)
            {
                if (left[2] === right[2])   
                {
                    var left1 = a.trackingNumber.match(/ORG ([A-Z]+)/);
                    var right2 = b.trackingNumber.match(/ORG ([A-Z]+)/);

                    return left1[1] - right1[1];
                }

                else return left[2] - right[2];
            }
            else
            {
                return left[1].length - right[1].length;
            }
        }

Any ideas on how to correct this?

有关如何纠正此问题的任何想法?

3 个解决方案

#1


1  

You could use Sorting with map and build a new array with the sort parameter.

您可以使用Sorting with map并使用sort参数构建一个新数组。

mapped.sort(function (a, b) {
    return a.cn[0] - b.cn[0] || a.cn[1] - b.cn[1] || a.tn[0].localeCompare(b.tn[0]) || a.tn[1] - b.tn[1];
    //        roman number         arabic number              organisation               number of org     
});

var myArray = [{ catNum: 'CAT I #4', trackingNumber: 'ORG Cat-123' }, { catNum: 'CAT I #6', trackingNumber: 'ORG Dog-345' }, { catNum: 'CAT I #2', trackingNumber: 'ORG Cat-123' }, { catNum: 'CAT I #2', trackingNumber: 'ORG Cat-345' }, { catNum: 'CAT II #15', trackingNumber: 'ORG Fish-264' }, { catNum: 'CAT III #1', trackingNumber: 'ORG Bird-123' }, { catNum: 'CAT II #7', trackingNumber: 'ORG Dog-533' }],
    mapped = myArray.map(function (a, i) {
        var cn = a.catNum.match(/CAT ([IV]+) #([0-9]+)/),
            tn = a.trackingNumber.match(/ORG ([A-Z]+)-([0-9]+)/i);
        cn.shift();
        cn[0] = { I: 1, II: 2, III: 3, IV: 4, V: 5, VI: 6, VII: 7, VIII: 8 }[cn[0]];
        tn.shift();
        return { index: i, cn: cn, tn: tn };
    }),
    result;

mapped.sort(function (a, b) {
    return a.cn[0] - b.cn[0] || a.cn[1] - b.cn[1] || a.tn[0].localeCompare(b.tn[0]) || a.tn[1] - b.tn[1];
});

result = mapped.map(function (el) {
    return myArray[el.index];
});

console.log(result);

#2


0  

How about this?

这个怎么样?

function catTrackSort(a, b)
{
    if (a.catNum == b.catNum) {
        // in case the tracking nums are also equal, return 0 to leave order unchanged
        if (a.trackingNumber == b.trackingNumber) {
            return 0;
        }

        // try sorting the tracking nums alphabetically
        var testABC = [a.trackingNumber, b.trackingNumber]
        testABC.sort() // default behavior is to sort by ABC

        // check if the test array changed order
        if (testABC[0] == a.trackingNumber) {
            return -1;
        }
        else {
            return 1;
        }
    }
    else {
        // logic to sort by catNum goes here
    }
}

Seems to work ok in my fiddle.

似乎在我的小提琴中工作正常。

#3


-1  

My JavaScript is not so hot, but here is an example of how to do it in C# for anyone who is interested.

我的JavaScript并不热,但这里有一个如何在C#中为感兴趣的人做这个的例子。

// Set up some sample data
var numbers = new List<Tuple<int, int>>();
var rand = new Random((int)DateTime.Now.Ticks);

for(int i = 0; i < 100; i++)
{
    numbers.Add(new Tuple<int, int>(rand.Next(10), rand.Next(10)));
}

// Get a collection of groups of the first item in the tuple
var groups = numbers.GroupBy(n => n.Item1).OrderBy(g => g.Key).ToList();

List<Tuple<int, int>> sortedNumbers = new List<Tuple<int, int>>();

// Create a new list by ordering each group by the second item in the tuple
groups.ForEach(g => sortedNumbers.AddRange(g.OrderBy(n => n.Item2)));

sortedNumbers.ForEach(sn => Console.WriteLine($"{sn.Item1} {sn.Item2}"));

#1


1  

You could use Sorting with map and build a new array with the sort parameter.

您可以使用Sorting with map并使用sort参数构建一个新数组。

mapped.sort(function (a, b) {
    return a.cn[0] - b.cn[0] || a.cn[1] - b.cn[1] || a.tn[0].localeCompare(b.tn[0]) || a.tn[1] - b.tn[1];
    //        roman number         arabic number              organisation               number of org     
});

var myArray = [{ catNum: 'CAT I #4', trackingNumber: 'ORG Cat-123' }, { catNum: 'CAT I #6', trackingNumber: 'ORG Dog-345' }, { catNum: 'CAT I #2', trackingNumber: 'ORG Cat-123' }, { catNum: 'CAT I #2', trackingNumber: 'ORG Cat-345' }, { catNum: 'CAT II #15', trackingNumber: 'ORG Fish-264' }, { catNum: 'CAT III #1', trackingNumber: 'ORG Bird-123' }, { catNum: 'CAT II #7', trackingNumber: 'ORG Dog-533' }],
    mapped = myArray.map(function (a, i) {
        var cn = a.catNum.match(/CAT ([IV]+) #([0-9]+)/),
            tn = a.trackingNumber.match(/ORG ([A-Z]+)-([0-9]+)/i);
        cn.shift();
        cn[0] = { I: 1, II: 2, III: 3, IV: 4, V: 5, VI: 6, VII: 7, VIII: 8 }[cn[0]];
        tn.shift();
        return { index: i, cn: cn, tn: tn };
    }),
    result;

mapped.sort(function (a, b) {
    return a.cn[0] - b.cn[0] || a.cn[1] - b.cn[1] || a.tn[0].localeCompare(b.tn[0]) || a.tn[1] - b.tn[1];
});

result = mapped.map(function (el) {
    return myArray[el.index];
});

console.log(result);

#2


0  

How about this?

这个怎么样?

function catTrackSort(a, b)
{
    if (a.catNum == b.catNum) {
        // in case the tracking nums are also equal, return 0 to leave order unchanged
        if (a.trackingNumber == b.trackingNumber) {
            return 0;
        }

        // try sorting the tracking nums alphabetically
        var testABC = [a.trackingNumber, b.trackingNumber]
        testABC.sort() // default behavior is to sort by ABC

        // check if the test array changed order
        if (testABC[0] == a.trackingNumber) {
            return -1;
        }
        else {
            return 1;
        }
    }
    else {
        // logic to sort by catNum goes here
    }
}

Seems to work ok in my fiddle.

似乎在我的小提琴中工作正常。

#3


-1  

My JavaScript is not so hot, but here is an example of how to do it in C# for anyone who is interested.

我的JavaScript并不热,但这里有一个如何在C#中为感兴趣的人做这个的例子。

// Set up some sample data
var numbers = new List<Tuple<int, int>>();
var rand = new Random((int)DateTime.Now.Ticks);

for(int i = 0; i < 100; i++)
{
    numbers.Add(new Tuple<int, int>(rand.Next(10), rand.Next(10)));
}

// Get a collection of groups of the first item in the tuple
var groups = numbers.GroupBy(n => n.Item1).OrderBy(g => g.Key).ToList();

List<Tuple<int, int>> sortedNumbers = new List<Tuple<int, int>>();

// Create a new list by ordering each group by the second item in the tuple
groups.ForEach(g => sortedNumbers.AddRange(g.OrderBy(n => n.Item2)));

sortedNumbers.ForEach(sn => Console.WriteLine($"{sn.Item1} {sn.Item2}"));