使条件函数更有效

时间:2019-05-24 01:49:37

标签: javascript jquery html arrays function

我想创建一个函数,可以根据给定的参数修改变量。

该函数检查变量和该字符串中的数字。然后通过参数指定将数字增加或减少1(++ 1)。

还有一个数组,如果数字等于数组的长度,则变为1;如果数字小于1,则等于数组的大小。这是为了确保字符串的数量不小于1或大于数组的长度。

带有数字的字符串为Music1。因此圈子将像: ...., Music1, Music2, Music3, Music4, Music1, Music2, Music3, ....

var MyArray = ["Music1", "Music2", "Music3", "Music4"];
var currentMusic = "Music1";

$(".increase").on('click tap', nextMusic);
$(".decrease").on('click tap', previousMusic);

function nextMusic() {
  unaryChange('plus')
}

function previousMusic() {
  unaryChange('minus')
}

function unaryChange(operation) {
  if (currentMusic === "Music4") {
    currentMusic = "Music1"
  } else if (currentMusic === "Music0") {
    currentMusic = "Music4"
  }
  if (operation === "plus") {
    currentMusic = currentMusic.replace(/\d+$/, function(n) {
      return ++n
    });
  } else {
    currentMusic = currentMusic.replace(/\d+$/, function(n) {
      return --n
    });
  }

  console.log(currentMusic);
  $(".text").text(currentMusic);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<button class="increase">increase</button>
<button class="decrease">decrease</button>
<p class="text">value</p>

以上方法几乎可以完成工作,但是我正在寻找一种更简单,更专业的解决方案。它看起来效率不高。例如,必须有一种更好的方法来指定参数operation而不是plus之类的字符串或条件。

我需要以更好的方式,更专业地重写此功能,并按所述方式工作。

谢谢。

6 个答案:

答案 0 :(得分:4)

最好使用数组索引而不是值

function unaryChange(operation) {
  var currentIndex = MyArray.findIndex(function(item) {
    return item === currentMusic;
  });

  if(operation === 'plus') {
    newIndex = currentIndex < MyArray.length - 1 && currentIndex + 1 || 0;
  } else {
    newIndex = currentIndex > 0 ? currentIndex -1 : MyArray.length -1;
  }

  currentMusic = MyArray[newIndex]
  $(".text").text(currentMusic);
}

在这种情况下,无论数组大小如何,它都会起作用。

工作示例https://jsbin.com/rahomorupa/4/edit?html,js,console,output

答案 1 :(得分:3)

Joe's answer为基础,建议您将plusminus的常量分别定义为+1-1,以简化递增/递减逻辑,以及the modulus operator来处理数组环绕:

const PLUS = 1;
const MINUS = -1;

function unaryChange(operation) {
  var currentIndex = MyArray.findIndex(function(item) {
    return item === currentMusic;
  });

  // If it's invoked as unaryChange(PLUS) or unaryChange(MINUS)
  // we don't need any conditional logic to handle the increment,
  // and with the % operator we don't need additional bounds overflow
  // logic. (This latter bit is complicated somewhat by the need to
  // handle a minus step from index 0.)
  const {length} = MyArray;
  const newIndex = ((currentIndex + operation) % length + length) % length;

  currentMusic = MyArray[newIndex]
  $(".text").text(currentMusic);
}

%运算符返回除法的余数,当与针对数组长度的数组索引一起使用时,该除法方便地循环回到0:

const array = ['first', 'second', 'third'];

for (let i = 0; i < 20; i++) {
  console.log(array[i % array.length]);
}

答案 2 :(得分:2)

您可以为plus传递布尔值,使用箭头函数和三元运算符:

var MyArray = ["Music1", "Music2", "Music3", "Music4"];
var currentMusic = "Music1";

$(".increase").on('click tap', nextMusic);
$(".decrease").on('click tap', previousMusic);

function nextMusic() {
  unaryChange(true)
}

function previousMusic() {
  unaryChange(false)
}

function unaryChange(plus) {
  currentMusic = currentMusic == "Music4" ? "Music1" : (currentMusic == "Music0" ? "Music4" : currentMusic);
  currentMusic = currentMusic.replace(/\d+$/, n => plus ? ++n : --n);
  console.log(currentMusic);
  $(".text").text(currentMusic);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<button class="increase">increase</button>
<button class="decrease">decrease</button>
<p class="text">value</p>

答案 3 :(得分:1)

我认为这是一个好的开始。访问数组的索引与值之间的关系感觉要干净得多。使用三元也将很多逻辑清理为一行。

var MyArray = ["Music1", "Music2", "Music3", "Music4"];
var currentMusic = 0;

$(".increase").on('click tap', unaryChange);
$(".decrease").on('click tap', unaryChange);

function unaryChange() {
  if (event.target.className === "increase") {
    currentMusic = (currentMusic < 3 ? currentMusic + 1 : 0)
  } else {
    currentMusic = (currentMusic > 0 ? currentMusic -= 1 : 3) 
  }
  console.log(MyArray[currentMusic]);
  $(".text").text(MyArray[currentMusic]);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<button class="increase">increase</button>
<button class="decrease">decrease</button>
<p class="text">value</p>

答案 4 :(得分:1)

这就是我要做的。由于“音乐”一词似乎只是用于指定特定单位的前缀,因此,我不会将其反复存储在数组中。 至于jQuery?是的,不。

"use strict";
function byId(id){return document.getElementById(id)}

window.addEventListener('load', onLoaded, false);

function onLoaded(evt)
{
	let prefix = 'Music';
	let count = 4, index=0;
	byId('increase').addEventListener('click', function(evt){index++; index %= count; update();}, false);
	byId('decrease').addEventListener('click', function(evt){index--; if (index<0) index=count-1; update();}, false);
	
	function update()
	{
		byId('status').textContent = `${prefix}${index+1}`;
	}
}
<span id='status'>Music1</span><br>
<button id='increase'>+</button><button id='decrease'>-</button>

答案 5 :(得分:1)

由于您拥有多种音乐,因此最好使用它。无需对文本进行操作,只需要将数组索引更新为下一个值,并将其传递给函数,然后直接获取歌曲名称即可。

由于我们希望介于0的边界和数组长度之间,因此可以使用以下方法:

  • 获取下一首歌曲:(currentTrackIndex + 1) % tracks.length。这将获得下一个索引值并对其取模,因此如果它超过数组长度,它将四舍五入。
  • 获取上一首歌曲:(currentTrackIndex - 1 + tracks.length) % tracks.length。它与获取下一首歌曲几乎相同,除非索引已为零。如果对负数取模,则会得到负数结果,并且会弄乱数组索引。因此,我们不使用条件子句(“ if (currentTrackIndex === 0 ...)”),而是添加数组长度。为什么?因为从0 % n == 0n % n == 0开始,增加数组长度不会改变模的结果,同时将索引保持为正数。

(我将名称从MyArray更改为tracks,将unaryChange更改为changeTrack,以使其含义更清晰)

var tracks = ["Music1", "Music2", "Music3", "Music4"];

var currentTrackIndex = 0;

$(".increase").on('click tap', nextMusic);
$(".decrease").on('click tap', previousMusic);

function nextMusic() {
  //It will move to the next track. If it's over the array length, it will reset to 0
  changeTrack((currentTrackIndex + 1) % tracks.length)
}

function previousMusic() {
  //It will move to the previous song. If it's below zero, it will reset to the last track index
  changeTrack((currentTrackIndex + tracks.length - 1) % tracks.length)
}

function changeTrack(newTrackIndex) {
  currentTrackIndex = newTrackIndex;
  var currentTrack = tracks[currentTrackIndex];
  console.log(currentTrackIndex);
  $(".text").text(currentTrack);
}