使用javascript对皇家名称进行排序

问题描述 投票:-1回答:3

我想对王室名称进行排序。对字母表的第一个偏好。如果两个名字相同,那么我想按罗马数字排序。例如,输入为:King III,King II,Queen IX。 (因为前2个字符串相同,所以需要按照附加的罗马数字进行排序)所以预期输出:King II,King III,Queen IX。

我尝试在罗马地图中存储罗马数字并编写一个函数,将给定数组中的罗马数字替换为King 2,King 3,Queen 9,然后尝试排序,但无法正确实现。有人可以帮我这个吗?

javascript arrays sorting
3个回答
3
投票

function romanToNum(roman) {
  if (roman === "")           return 0;
  if (roman.startsWith("L"))  return 50 + romanToNum(roman.substr(1));
  if (roman.startsWith("XL")) return 40 + romanToNum(roman.substr(2));
  if (roman.startsWith("X"))  return 10 + romanToNum(roman.substr(1));
  if (roman.startsWith("IX")) return 9  + romanToNum(roman.substr(2));
  if (roman.startsWith("V"))  return 5  + romanToNum(roman.substr(1));
  if (roman.startsWith("IV")) return 4  + romanToNum(roman.substr(2));
  if (roman.startsWith("I"))  return 1  + romanToNum(roman.substr(1));
  return 0;
}
console.log(
    ["King III", "King II", "Queen IX"]
      .map((n) => ({name: n, num: romanToNum(n.split(" ").pop())}))
      .sort((a, b) => (a.num - b.num))
      .map(({name, num}) => name)
  );

romanToNum功能改编自this answer。首先将数组映射到{name, num}对象,然后在num上排序,然后仅转换回names。


1
投票

您可以拆分字符串并使用sorting with map,同时将该元素的每个元素与另一个元素的每个元素进行比较。如果两个元素都是数字,则取差异,否则返回localeCompare的结果。

function customSort(data, order) {

    function isNumber(v) {
        return (+v).toString() === v;
    }

    function isRoman(s) {
        // http://stackoverflow.com/a/267405/1447675
        return /^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$/i.test(s);
    }

    function parseRoman(s) {
        var val = { M: 1000, D: 500, C: 100, L: 50, X: 10, V: 5, I: 1 };
        return s.toUpperCase().split('').reduce(function (r, a, i, aa) {
            return val[a] < val[aa[i + 1]] ? r - val[a] : r + val[a];
        }, 0);
    }

    var sort = {
            asc: function (a, b) {
                var i = 0,
                    l = Math.min(a.value.length, b.value.length);

                while (i < l && a.value[i] === b.value[i]) {
                    i++;
                }
                if (i === l) {
                    return a.value.length - b.value.length;
                }
                if (isNumber(a.value[i]) && isNumber(b.value[i])) {
                    return a.value[i] - b.value[i];
                }
                if (isRoman(a.value[i]) && isRoman(b.value[i])) {
                    return parseRoman(a.value[i]) - parseRoman(b.value[i]);
                }
                return a.value[i].localeCompare(b.value[i]);
            },
            desc: function (a, b) {
                return sort.asc(b, a);
            }
        },
        mapped = data.map(function (el, i) {
            var string = el.replace(/\d(?=[a-z])|[a-z](?=\.)/gi, '$&. .'),
                regex = /(\d+)|([^0-9.]+)/g,
                m,
                parts = [];

            while ((m = regex.exec(string)) !== null) {
                parts.push(m[0]);
            }
            return { index: i, value: parts, o: el, string: string };
        });

    mapped.sort(sort[order] || sort.asc);
    return mapped.map(function (el) {
        return data[el.index];
    });
}

var arr = ['King III', 'King II', 'Queen IX'];

console.log('sorted array asc', customSort(arr));
console.log('sorted array desc', customSort(arr, 'desc'));
console.log('original array', arr);
.as-console-wrapper { max-height: 100% !important; top: 0; }

0
投票

使用您自己的转换表来获取罗马数字的十进制值,而不是使用正确的回调进行简单排序

var romanNumberToDec = {
  "I" : 1, "II" : 2, "III" : 3, "IV" : 4, "V" : 5,
  "VI" : 6, "VII" : 7, "VIII" : 8, "IX" : 9, "X" : 10
}

ES6console与桌子

如果这就是你需要处理的全部内容

但如果你需要更通用的方式 - from selftaughtjs -

function fromRoman(str) {  
   var result = 0;
   // the result is now a number, not a string
   var decimal = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
   var roman = ["M", "CM","D","CD","C", "XC", "L", "XL", "X","IX","V","IV","I"];
   for (var i = 0;i<=decimal.length;i++) {
       while (str.indexOf(roman[i]) === 0){
         result += decimal[i];
         str = str.replace(roman[i],'');
       }
   }
   return result;
}


var arrayObj = [ "King III", "King II", "Queen IX"];

function mySort() {
    arrayObj.sort( (a, b)=> {
      let aNum = a.substr(a.lastIndexOf(" ") + 1, a.length);
      let bNum = b.substr(b.lastIndexOf(" ") + 1, b.length);
      // return romanNumberToDec[aNum] - romanNumberToDec[bNum]; 
      return fromRoman(aNum) - fromRoman(bNum);
    });
    console.log(arrayObj);
};

mySort();

ES6console的通用方式

© www.soinside.com 2019 - 2024. All rights reserved.