草庐IT

第一百一十三篇: JS数组Array(二)数组方法 栈、队列、排序

养肥胖虎 2023-03-28 原文

好家伙, 

 

在上一篇中,我们知道了,

JS的数组中每个槽位可以存储任意类型的数据

那么,我们能通过数组去模仿某些数据结构吗?

答案是肯定的

 

1.栈方法

ECMAScript 给数组提供几个方法,让它看起来像是另外一种数据结构。

数组对象可以像栈一样,也就是一种限制插人和删除项的数据结构。

栈是一种后进先出(LIFO,Last-In-First-Out)的结构,也就是最近添加的项先被删除。

数据项的插入(称为推入,push)和删除(称为弹出,pop)只在栈的一个地方发生,即栈顶

ECMAScript数组提供了push()和pop()方法,以实现类似栈的行为。
push()方法接收任意数量的参数,并将它们添加到数组末尾,返回数组的最新长度。

pop()方法则用于删除数组的最后一项,同时减少数组的1ength值,返回被删除的项。

用法示例:

let colors = ["red", "blue", "green"]; //定义一个字符串数组
let cpush = colors.push("black");
console.log(colors,cpush);

let cpop = colors.pop();
console.log(colors,cpop);

 

 

 

 (这张图,没有十年画工画不出来)

 

 

2.队列方法

2.1.正队列

就像栈是以LIFO形式限制访问的数据结构一样,队列以先进先出(FIFO,First-In-First-Out)形式限制访问。

队列在列表末尾添加数据,但从列表开头获取数据。

因为有了在数据末尾添加数据的push()方法,所以要模拟队列就差一个从数组开头取得数据的方法了。

这个数组方法叫shift(),它会删除数组的第一项并返回它,然后数组长度减1。

使用shift()和push(),可以把数组当成队列来使用

 

用法示例:

let colors = ["red", "blue", "green"]; //定义一个字符串数组
let cpush = colors.push("black");
console.log(colors,cpush);

let cshift = colors.shift();
console.log(colors,cshift);
console.log(colors,colors.shift());

 

 

 

 

2.2.逆队列

ECMAScript也为数组提供了unshift()方法。

顾名思义,unshift()就是执行跟shift()相反的操作:在数组开头添加任意多个值,然后返回新的数组长度。

通过使用 unshift()和pop(),可以在相反方向上模拟队列,即在数组开头添加新数据,在数组末尾取得数据, 

用法示例:

let colors = ["red", "blue", "green"]; //定义一个字符串数组
let cunshift = colors.unshift("black");
console.log(colors,cunshift);

let cpop = colors.pop();//将出队元素重新插回队头
colors.unshift(cpop);

console.log(colors,cpop);
console.log(colors,colors.pop());

 

 

 

 (这张图,没有十年画工画不出来)

 

 

3.排序方法

 数组有两个方法可以用来对元素重新排序:reverse()和sort()。

3.1.reverse()反转数组方法

顾名思义,reverse()方法就是将数组元素反向排列。

用法示例:

let colors = ["red", "blue", "green"]; //定义一个字符串数组
colors.reverse();
console.log(colors);

 

 (貌似一些基础面试题会有类似的题目,叫你去反转某个数组,这么干就对了)

 

 

3.2.sort()排序方法

按照官方的说法,这是一个排序方法,

 

默认情况下,sort()会按照升序重新排列数组元素,即最小的值在前面,最大的值在后面。

 

为此,sort()会在每一项上调用string()转型函数,然后比较字符串来决定顺序。

 

但他并不总是能得到正确的排序

let colors = [99999,99,999,9999,9]; 
colors.sort();
console.log(colors);

colors_1 =[9, 99, 999, 9999, 99999];
colors_1.sort();
console.log(colors_1);

colors_2 =[0,1,5,10,15];
colors_2.sort();
console.log(colors_2);

 

 

 这里我们可以看到,第三个例子的排序错误了

 

为此,sort()方法可以接收一个比较函数,用于判断哪个值应该排在前面.

 

 

比较函数接收两个参数,

(1) 如果第一个参数应该排在第二个参数前面,就返回负值;

(2) 如果两个参数相等,就返回0;

(3) 如果第一个参数应该排在第二个参数后面,就返回正值。

function compare_1(valuel, value2){
    if (valuel < value2){
        return -1;
    }
    else if (valuel > value2) {
        return 1;
    }
    else{
        return 0;
    }
}

 

返回-1就不进行交换,返回1将对两个值对调

colors_2 = [0, 1, 5, 10, 15];

//从小到大排序
function compare_1(valuel, value2){
    if (valuel < value2){
        return -1;
    }
    else if (valuel > value2) {
        return 1;
    }
    else{
        return 0;
    }
}

//从大到小排序
function compare_2(valuel, value2){
    if (valuel < value2){
        return 1;
    }
    else if (valuel > value2) {
        return -1;
    }
    else{
        return 0;
    }
}

console.log(colors_2.sort(compare_1));
console.log(colors_2.sort(compare_2));

 

 

如果数组的元素是数值,或者是其valueOf()方法返回数值的对象(如Date对象),这个比较函数还可以写得更简单,

更简便的写法:

colors_2 = [0, 1, 5, 10, 15];
function compare_3(value1, value2){
    return value2-value1;
}

function compare_4(value1, value2){
    return value1-value2;
}
console.log(colors_2.sort(compare_3));
console.log(colors_2.sort(compare_4));

 

 

怎么说呢,感觉这个sort()设计的并不是很好,用起来并不是那么的方便,

要排序的话,或许直接写一个冒泡排序或者快速排序可以解决?

 

又或者是开发者故意开放一个比较函数来让我们编辑的?

JS-数组sort方法用的是哪种排序算法 - 简书 (jianshu.com)

等有了更多知识储备再来回答吧

 

有关第一百一十三篇: JS数组Array(二)数组方法 栈、队列、排序的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  4. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  5. ruby - 在 Ruby 中实现 `call_user_func_array` - 2

    我怎样才能完成http://php.net/manual/en/function.call-user-func-array.php在ruby中?所以我可以这样做:classAppdeffoo(a,b)putsa+benddefbarargs=[1,2]App.send(:foo,args)#doesn'tworkApp.send(:foo,args[0],args[1])#doeswork,butdoesnotscaleendend 最佳答案 尝试分解数组App.send(:foo,*args)

  6. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  7. Ruby 方法() 方法 - 2

    我想了解Ruby方法methods()是如何工作的。我尝试使用“ruby方法”在Google上搜索,但这不是我需要的。我也看过ruby​​-doc.org,但我没有找到这种方法。你能详细解释一下它是如何工作的或者给我一个链接吗?更新我用methods()方法做了实验,得到了这样的结果:'labrat'代码classFirstdeffirst_instance_mymethodenddefself.first_class_mymethodendendclassSecond使用类#returnsavailablemethodslistforclassandancestorsputsSeco

  8. ruby - 多次弹出/移动 ruby​​ 数组 - 2

    我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby​​数组,我们在StackOverflow上找到一

  9. ruby - 将数组的内容转换为 int - 2

    我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]

  10. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

随机推荐