English 中文(简体)
甲型混合体/数字阵列
原标题:Sort mixed alpha/numeric array

I have a mixed array that I need to sort by alphabet and then by digit

[A1, A10, A11, A12, A2, A3, A4, B10, B2, F1, F12, F3]

我如何认为:

[A1, A2, A3, A4, A10, A11, A12, B2, B10, F1, F3, F12]

我曾尝试过

arr.sort(function(a,b) {return a - b});

but that only sorts it alphabetically. Can this be done with either straight JavaScript or jQuery?

最佳回答

var reA = /[^a-zA-Z]/g;
var reN = /[^0-9]/g;

function sortAlphaNum(a, b) {
  var aA = a.replace(reA, "");
  var bA = b.replace(reA, "");
  if (aA === bA) {
    var aN = parseInt(a.replace(reN, ""), 10);
    var bN = parseInt(b.replace(reN, ""), 10);
    return aN === bN ? 0 : aN > bN ? 1 : -1;
  } else {
    return aA > bA ? 1 : -1;
  }
}
console.log(
["A1", "A10", "A11", "A12", "A2", "A3", "A4", "B10", "B2", "F1", "F12", "F3"].sort(sortAlphaNum)
)
问题回答
const sortAlphaNum = (a, b) => a.localeCompare(b,  en , { numeric: true })

使用:

const sortAlphaNum = (a, b) => a.localeCompare(b,  en , { numeric: true })
console.log([ A1 ,  A10 ,  A11 ,  A12 ,  A2 ,  A3 ,  A4 ,  B10 ,  B2 ,  F1 ,  F12 ,  F3 ].sort(sortAlphaNum))

Gives:

[A1”、“A2”、“A3”、“A4”、“A10”、“A11”、“A12”、“B2”、“B10”、“F1”、“F3”、“F12”>

你可能不得不将<条码>在上的论据更改到你的地方,或从方案上确定,但这一工程是用来修饰的。

localeCompare 得到IE11、Acre、Edpa、Emge、Embra和So10的支持。

我的情况类似,但是,甲型数字和复数混合在一起;数字,需要先分所有数字,然后是字母数字。

A10
1
5
A9
2
B3
A2

需要成为:

1
2
5
A2
A9
A10
B3

我能够使用所供应的算法和黑板,以达到这一目的:

var reA = /[^a-zA-Z]/g;
var reN = /[^0-9]/g;
function sortAlphaNum(a,b) {
    var AInt = parseInt(a, 10);
    var BInt = parseInt(b, 10);

    if(isNaN(AInt) && isNaN(BInt)){
        var aA = a.replace(reA, "");
        var bA = b.replace(reA, "");
        if(aA === bA) {
            var aN = parseInt(a.replace(reN, ""), 10);
            var bN = parseInt(b.replace(reN, ""), 10);
            return aN === bN ? 0 : aN > bN ? 1 : -1;
        } else {
            return aA > bA ? 1 : -1;
        }
    }else if(isNaN(AInt)){//A is not an Int
        return 1;//to make alphanumeric sort first return -1 here
    }else if(isNaN(BInt)){//B is not an Int
        return -1;//to make alphanumeric sort first return 1 here
    }else{
        return AInt > BInt ? 1 : -1;
    }
}
var newlist = ["A1", 1, "A10", "A11", "A12", 5, 3, 10, 2, "A2", "A3", "A4", "B10", "B2", "F1", "F12", "F3"].sort(sortAlphaNum);

这样做的一个简单办法是使用<代码>的地方Compare()方法。 Javacast <>code> https://www.w3schools.com/jsref/jsref_ localecompare.asp

例:

export const sortAlphaNumeric = (a, b) => {
    // convert to strings and force lowercase
    a = typeof a ===  string  ? a.toLowerCase() : a.toString();
    b = typeof b ===  string  ? b.toLowerCase() : b.toString();

    return a.localeCompare(b);
};

预期行为:

1000X Radonius Maximus
10X Radonius
200X Radonius
20X Radonius
20X Radonius Prime
30X Radonius
40X Radonius
Allegia 50 Clasteron
Allegia 500 Clasteron
Allegia 50B Clasteron
Allegia 51 Clasteron
Allegia 6R Clasteron
Alpha 100
Alpha 2
Alpha 200
Alpha 2A
Alpha 2A-8000
Alpha 2A-900
Callisto Morphamax
Callisto Morphamax 500
Callisto Morphamax 5000
Callisto Morphamax 600
Callisto Morphamax 6000 SE
Callisto Morphamax 6000 SE2
Callisto Morphamax 700
Callisto Morphamax 7000
Xiph Xlater 10000
Xiph Xlater 2000
Xiph Xlater 300
Xiph Xlater 40
Xiph Xlater 5
Xiph Xlater 50
Xiph Xlater 500
Xiph Xlater 5000
Xiph Xlater 58
var a1 =["A1", "A10", "A11", "A12", "A2", "A3", "A4", "B10", "B2", "F1", "F12", "F3"];

var a2 = a1.sort(function(a,b){
    var charPart = [a.substring(0,1), b.substring(0,1)],
        numPart = [a.substring(1)*1, b.substring(1)*1];

    if(charPart[0] < charPart[1]) return -1;
    else if(charPart[0] > charPart[1]) return 1;
    else{ //(charPart[0] == charPart[1]){
        if(numPart[0] < numPart[1]) return -1;
        else if(numPart[0] > numPart[1]) return 1;
        return 0;
    }
});

$( #r ).html(a2.toString())

http://jsfiddle.net/8fRsD/

这可以做到:

function parseItem (item) {
  const [, stringPart =   , numberPart = 0] = /(^[a-zA-Z]*)(d*)$/.exec(item) || [];
  return [stringPart, numberPart];
}

function sort (array) {
  return array.sort((a, b) => {
    const [stringA, numberA] = parseItem(a);
    const [stringB, numberB] = parseItem(b);
    const comparison = stringA.localeCompare(stringB);
    return comparison === 0 ? Number(numberA) - Number(numberB) : comparison;
  });
}

console.log(sort([ A1 ,  A10 ,  A11 ,  A12 ,  A2 ,  A3 ,  A4 ,  B10 ,  B2 ,  F1 ,  F12 ,  F3 ]))
console.log(sort([ a25b ,  ab ,  a37b ]))

我最近开展了一个涉及库存和双向地点的项目。 这些数据需要按本底地点分类,并且属于一系列物体。

对于想要处理这类数据分类的人,如果你的数据属于一系列目标,你可以这样做:

const myArray = [
    { location:  B3 ,   item:  A , quantity: 25 },
    { location:  A11 ,  item:  B , quantity: 5 },
    { location:  A6 ,   item:  C , quantity: 245 },
    { location:  A9 ,   item:  D , quantity: 15 },
    { location:  B1 ,   item:  E , quantity: 65 },
    { location:  SHOP , item:  F , quantity: 42 },
    { location:  A7 ,   item:  G , quantity: 57 },
    { location:  A3 ,   item:  H , quantity: 324 },
    { location:  B5 ,   item:  I , quantity: 4 },
    { location:  A5 ,   item:  J , quantity: 58 },
    { location:  B2 ,   item:  K , quantity: 45 },
    { location:  A10 ,  item:  L , quantity: 29 },
    { location:  A4 ,   item:  M , quantity: 11 },
    { location:  B4 ,   item:  N , quantity: 47 },
    { location:  A1 ,   item:  O , quantity: 55 },
    { location:  A8 ,   item:  P , quantity: 842 },
    { location:  A2 ,   item:  Q , quantity: 67 }
];

const sortArray = (sourceArray) => {
    const sortByLocation = (a, b) => a.location.localeCompare(b.location,  en , { numeric: true });
    //Notice that I specify location here ^^       and here        ^^ using dot notation
    return sourceArray.sort(sortByLocation);
};


console.log( unsorted: , myArray);

console.log( sorted by location: , sortArray(myArray));

你们也可以轻易地以任何其他钥匙分类。 在此情况下,<条码>项目或<条码> 使用氮中显示的 do。

Javascript Array 短期职能有1个任择性论点,比较职能。 你可以把这一职能与你的要求进行比较。

<代码>arr.sort([功能])

职能比较(选择)。 具体说明了哪类命令。 如果遗漏,则根据每个要素的细微转换,按照统法协会代码点值对阵列进行分类。 - MDN

Adding to the accepted answer from epascarello, since I cannot comment on it. I m still a noob here. When one of the strinngs doesn t have a number the original answer will not work. For example A and A10 will not be sorted in that order. Hence you might wamnt to jump back to normal sort in that case.

var reA = /[^a-zA-Z]/g;
var reN = /[^0-9]/g;
function sortAlphaNum(a,b) {
    var aA = a.replace(reA, "");
    var bA = b.replace(reA, "");
    if(aA === bA) {
      var aN = parseInt(a.replace(reN, ""), 10);
      var bN = parseInt(b.replace(reN, ""), 10);
      if(isNaN(bN) || isNaN(bN)){
        return  a > b ? 1 : -1;
      }
      return aN === bN ? 0 : aN > bN ? 1 : -1;
    } else {
     return aA > bA ? 1 : -1;
    }
 }
 ["A1", "A10", "A11", "A12", "A2", "A3", "A4", "B10", "B2", "F1", "F12","F3"].sort(sortAlphaNum);`

Only problem with the above given solution was that the logic failed when numeric data was same & alphabets varied e.g. 28AB, 28PQR, 28HBC. Here is the modified code.

var reA = /[^a-zA-Z]/g;
    var reN = /[^0-9]/g;
    var AInt = parseInt(a, 10);
    var BInt = parseInt(b, 10);
    if(isNaN(AInt) && isNaN(BInt)){
        var aA = a.replace(reA, "");
        var bA = b.replace(reA, "");
        if(aA === bA) {
            var aN = parseInt(a.replace(reN, ""), 10);
            var bN = parseInt(b.replace(reN, ""), 10);
            alert("in if "+aN+" : "+bN);
            return aN === bN ? 0 : aN > bN ? 1 : -1;
        } else {
            return aA > bA ? 1 : -1;
        }
    }else if(isNaN(AInt)){//A is not an Int
        return 1;//to make alphanumeric sort first return 1 here
    }else if(isNaN(BInt)){//B is not an Int
        return -1;//to make alphanumeric sort first return -1 here
    }else if(AInt == BInt) {
        var aA = a.replace(reA, "");
        var bA = b.replace(reA, "");
        return aA > bA ? 1 : -1;
    }
    else {
        return AInt > BInt ? 1 : -1;
    }

此处为ES6型字母升级至本回答。

export function SortAlphaNum(a: string, b: string) {
    const reA = /[^a-zA-Z]/g;
    const reN = /[^0-9]/g;
    const aA = a.replace(reA, "");
    const bA = b.replace(reA, "");
    if (aA === bA) {
      const aN = parseInt(a.replace(reN, ""), 10);
      const bN = parseInt(b.replace(reN, ""), 10);
      return aN === bN ? 0 : aN > bN ? 1 : -1;
    } else {
      return aA > bA ? 1 : -1;
    }
}

Well, just in case someone s looking for a cleaner approach using localeCompare

arr.sort((a, b) => a.localeCompare(b, undefined,{ numeric: true }))

我解决了上述问题,其文字如下。

arrVals.sort(function(a, b){
    //return b.text - a.text;
    var AInt = parseInt(a.text, 10);
    var BInt = parseInt(b.text, 10);

    if ($.isNumeric(a.text) == false && $.isNumeric(b.text) == false) {
        var aA = a.text
        var bA = b.text;
        return aA > bA ? 1 : -1;
    } else if ($.isNumeric(a.text) == false) {  // A is not an Int
        return 1;    // to make alphanumeric sort first return -1 here
    } else if ($.isNumeric(b.text) == false) {  // B is not an Int
        return -1;   // to make alphanumeric sort first return 1 here
    } else {
        return AInt < BInt ? 1 : -1;
    }
});

这对一大批混杂的阵列做了罚款。

谢谢。

alphaNumericCompare(a, b) {

    let ax = [], bx = [];

    a.replace(/(d+)|(D+)/g, function (_, $1, $2) { ax.push([$1 || Infinity, $2 ||   ]) });
    b.replace(/(d+)|(D+)/g, function (_, $1, $2) { bx.push([$1 || Infinity, $2 ||   ]) });

    while (ax.length && bx.length) {
       let an = ax.shift();
       let bn = bx.shift();
       let nn = (an[0] - bn[0]) || an[1].localeCompare(bn[1]);
       if (nn) {
         return nn;
       }
     }
     return ax.length - bx.length;
}

这对我来说是可行的,它只是一个更细微的契约。

const reg = /[0-9]+/g;

array.sort((a, b) => {
     let v0 = a.replace(reg, v => v.padStart(10,  0 ));
     let v1 = b.replace(reg, v => v.padStart(10,  0 ));
     return v0.localeCompare(v1);
});

此处的版本(根据@SunnyPenguin &@Code Maniac的答复)作为图书馆功能。 更新和复制可变名称;评论意见为明确性增添了内容。

// Sorts strings with numbers by keeping the numbers in ascending order
export const sortAlphaNum: Function = (a: string, b: string, locale: string): number => {
  const letters: RegExp = /[^a-zA-Z]/g;
  const lettersOfA: string = a.replace(letters,   );
  const lettersOfB: string = b.replace(letters,   );

  if (lettersOfA === lettersOfB) {
    const numbers: RegExp = /[^0-9]/g;
    const numbersOfA: number = parseInt(a.replace(numbers,   ), 10);
    const numbersOfB: number = parseInt(b.replace(numbers,   ), 10);

    if (isNaN(numbersOfA) || isNaN(numbersOfB)) {
      // One is not a number - comparing letters only
      return new Intl.Collator(locale, { sensitivity:  accent  }).compare(a, b);
    }
    // Both have numbers - compare the numerical parts
    return numbersOfA === numbersOfB ? 0 : numbersOfA > numbersOfB ? 1 : -1;
  } else {
    // Letter parts are different - comparing letters only
    return new Intl.Collator(locale, { sensitivity:  accent  }).compare(lettersOfA, lettersOfB);
  }
};




相关问题
selected text in iframe

How to get a selected text inside a iframe. I my page i m having a iframe which is editable true. So how can i get the selected text in that iframe.

How to fire event handlers on the link using javascript

I would like to click a link in my page using javascript. I would like to Fire event handlers on the link without navigating. How can this be done? This has to work both in firefox and Internet ...

How to Add script codes before the </body> tag ASP.NET

Heres the problem, In Masterpage, the google analytics code were pasted before the end of body tag. In ASPX page, I need to generate a script (google addItem tracker) using codebehind ClientScript ...

Clipboard access using Javascript - sans Flash?

Is there a reliable way to access the client machine s clipboard using Javascript? I continue to run into permissions issues when attempting to do this. How does Google Docs do this? Do they use ...

javascript debugging question

I have a large javascript which I didn t write but I need to use it and I m slowely going trough it trying to figure out what does it do and how, I m using alert to print out what it does but now I ...

Parsing date like twitter

I ve made a little forum and I want parse the date on newest posts like twitter, you know "posted 40 minutes ago ","posted 1 hour ago"... What s the best way ? Thanx.

热门标签