【问题标题】:Sorting an array of strings and numbers while maintaining the array's original order对字符串和数字数组进行排序,同时保持数组的原始顺序
【发布时间】:2017-05-15 15:15:18
【问题描述】:

我刚刚参加了一次编码面试(呃。),我这辈子都想不通。

问题

双重排序
请编写一个接受字符串数组的 javascript 方法。每个元素可以是数字(“165”)或单词(“dog”)。您的方法应该对数组进行排序并返回,使得 (1) 单词按字母顺序排列,数字按数字顺序排列,(2) 数组中单词和数字的顺序相同。

示例(输入 => 输出):

排序(['5', '4', '狗', '1', '猫'])

=> ['1', '4', '猫', '5', '狗']

排序(['狗','猫'])

=> ['猫','狗']

排序('5', '3')

=> ['3', '5']

我能够编写一个按字母和数字对数组进行排序的基本排序函数,但我无法保持数组的原始顺序。这是我在时限内想出的:

var multiSortArray = [5, 4, 'dog', 1, 'cat'];

var multiSort = function(arr) {
    var sortedArray = arr.sort();
    console.log(sortedArray);
}
multiSort(multiSortArray); 
which outputs: [1, 4, 5, "cat", "dog"]  

任何帮助将不胜感激,我很恼火,我无法弄清楚这一点。我在 SO 中所能找到的只是订购 objects 我不确定我需要做什么(或者我可能会这样做。我不知道。)

谢谢大家!

【问题讨论】:

  • 我相信它应该对字符串和数字进行排序,但将它们保留在原来的位置。所以 [3, 5, 'cat', 2, 'ant'] --> [2, 3, 'ant', 4, 'cat']。因此数字索引仍然是索引,与字符串相同,但除此之外它们按字母/数字排序。
  • @T.J.Crowder 我认为应该对数组进行排序,但是最初是字符串的数组位置应该保持为字符串,而最初保存整数的数组位置应该保持整数。跨度>
  • 我认为正确的输出应该是 - [1, 4, 'cat', 5, 'dog']
  • @zenwraight OP 在他的问题中说,这是他的第一个例子。他是说他自己的输出是错误的。
  • 他们真的把数字作为字符串给你了吗?

标签: javascript arrays sorting


【解决方案1】:

只需将数字和单词拆分为单独的数组,对它们进行排序,然后再次加在一起

function sort(arr) {
  let n = arr.filter(x =>  isNaN(x)).sort((a,b) => a.localeCompare(b));
  let c = arr.filter(y => !isNaN(y)).sort((a,b) => a-b);

  return arr.map(z => (isNaN(z) ? n : c).shift());
}

console.log(sort(['5', '4', 'dog', '1', 'cat']));

【讨论】:

  • 如果字符串是""怎么办? ;-)
  • ["14", "111"].
  • 简洁...几个问题,我是初学者到中级水平,所以当我掌握要点时,该过程的一些更精细的点就在我的脑海中 1 isNan -我没有'以前没见过,这是e6的一部分吗?基本上,测试 (x) 的值是否为 NaN?我没有看到它在任何地方宣布,所以我想它必须是。 2 仍然没有在我的 e6 上运行,=> 是否像在 filter() 中声明一个匿名函数? 3 在这种情况下,z 是什么?非常感谢你和我一起经历这一切。我想确保我真的理解它,以免招聘经理想要讨论它
  • @ibrahimmahrir - 好点,应该将数字字符串排序为实际数字,已编辑。
  • @adeneo:它的工作是一个愉快的巧合。 :-) 实际上,它的频率令人惊讶。
【解决方案2】:

一种方法:

var arr = ['5', '4', 'dog', '1', 'cat'];

// STEP 1: split the original array into two arrays, one for strings and one for numbers
var str = [], num = [];
arr.forEach(e => isNaN(e)? str.push(e): num.push(e));

// STEP 2: sort the two arrays
str.sort();
num.sort((a, b) => a - b); // because the numbers are actually strings we need to do a - b to implicitly convert them into numbers and sort them using the substraction result

// STEP 3: for each element in the original array, if the original item was a string then replace it with the first item in the string array (and remove the added item), if the original item was a number, do the same with the num array
arr.forEach((e, i) => arr[i] = isNaN(e)? str.shift(): num.shift());

console.log(arr);

【讨论】:

  • 虽然他们都是对的,但这是我理解得足以谈论的一个。感谢大家花时间帮助一位女士:)
【解决方案3】:

我想到的第一件事就是制作一张地图,说明哪种类型的东西在哪个索引中,然后分离和排序,然后根据类型再次将它们压缩在一起:

function sort(a) {
    const type = a.map(e => /^\d+$/.test(e));
    const nums = a.filter((e, i) => type[i]).sort((left, right) => left - right);
    const strs = a.filter((e, i) => !type[i]).sort((left, right) => left.localeCompare(right));
    let nindex = 0, sindex = 0;
    return type.map(t => t ? nums[nindex++] : strs[sindex++]);
}

console.log(sort(['5', '4', 'dog', '1', 'cat']));
// => ['1', '4', 'cat', '5', 'dog']

console.log(sort(['dog', 'cat']));
// => ['cat', 'dog']

console.log(sort(['5', '3']));
// => ['3', '5']

console.log(sort(['5', 'gazelle', '300']));
// => ['5', 'gazelle', '300']

function sort(a) {
    const type = a.map(e => /^\d+$/.test(e));
    const nums = a.filter((e, i) => type[i]).sort((left, right) => left - right);
    const strs = a.filter((e, i) => !type[i]).sort((left, right) => left.localeCompare(right));
    let nindex = 0, sindex = 0;
    return type.map(t => t ? nums[nindex++] : strs[sindex++]);
}
.as-console-wrapper {
  max-height: 100% !important;
}

或者使用 ES5 和更早的语法:

console.log(sort(['5', '4', 'dog', '1', 'cat']));
// => ['1', '4', 'cat', '5', 'dog']

console.log(sort(['dog', 'cat']));
// => ['cat', 'dog']

console.log(sort(['5', '3']));
// => ['3', '5']

console.log(sort(['5', 'gazelle', '300']));
// => ['5', 'gazelle', '300']

function sort(a) {
    var type = a.map(function(e) { return /^\d+$/.test(e); });
    var nums = a.filter(function(e, i) { return type[i]; }).sort(function(left, right) {
        return left - right;
    });
    var strs = a.filter(function(e, i) { return !type[i]; }).sort(function(left, right) {
        return left.localeCompare(right);
    });
    var nindex = 0, sindex = 0;
    return type.map(function(t) {
        return t ? nums[nindex++] : strs[sindex++];
    });
}
.as-console-wrapper {
  max-height: 100% !important;
}

...但我会问他们一堆关于数据的问题,因为如果有数十万个条目,我可能会走另一条路。

还要注意确保对数字进行数字比较,并对字符串进行正确的字典比较(无论如何,在浏览器的功能集中)。


旁注:在我的版本中,我检测到这样的数字:/^\d+$/.test(e)。这只允许整数,不允许使用科学记数法。另一种方法是改变 adeneo 所做的:e !== "" && !isNaN(e),如果它不为空,它将强制 e 为一个数字,并检查结果是否为 NaN(这意味着它无法转换)。检查"" 是因为可悲的是,将"" 强制为数字会给你0,所以isNaN(e) 会给"" 提供不正确的结果。

【讨论】:

    【解决方案4】:

    这有点快而且效率不高,但它是一种可以产生输出的潜在解决方案:

    var sorter = function(array){
      let chars = [];
      let nums = [];
    
      array.forEach( (v,i) => {
        if(isNaN(+v)){
            chars.push(i);
        }
        else{
            nums.push(i);
        }
      });
    
      let newArray = [];
    
      let sortedChars = array.filter(a => isNaN(+a)).sort();
      let sortedNums = array.filter(a => !isNaN(+a)).sort();
    
      chars.forEach((value, index) => {
        newArray[value] = sortedChars[index];
      });
    
       nums.forEach((value, index) => {
        newArray[value] = sortedNums[index];
      });
    
      return newArray;
    }
    

    【讨论】:

      【解决方案5】:

      这可以通过多种方式轻松完成,因此您可以将排序数组设为

      [1,4,5,'cat','dog']
      

      所以在排序之前取另一个相同大小的数组并做一个标记

      0 - means integer
      1 - means string 
      

      所以这个新数组看起来像这样

      temp = [0, 0, 1, 0, 1];
      

      现在,在您完成排序之后,只需对其进行迭代,并按顺序将 0 替换为传入的整数,将 1 替换为字符串

      您将获得所需的输出。

      【讨论】:

        【解决方案6】:

        您可以将对象用于键入的值并进行相应的排序。然后再次使用原始数组并将结果集的值映射为相同类型。

        function sort(array) {
            var order = {
                    number: function (a, b) { return a - b; },
                    string: function (a, b) { return a.localeCompare(b); },
                    default: function () { return 0; },
                };
                temp = {};
        
            array.forEach(function (a) { (temp[typeof a] = temp[typeof a] || []).push(a); });
            Object.keys(temp).forEach(function (t) { temp[t].sort(order[t] || order.default); });
            return array.map(function (a) { return temp[typeof a].shift(); });
        };
        
        console.log(sort([5, 4, 'dog', 1, 'cat']));
        .as-console-wrapper { max-height: 100% !important; top: 0; }

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-12-19
          • 2021-03-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多