我想创建一个函数,可以根据给定的参数修改变量。
该函数检查变量和该字符串中的数字。然后通过参数指定将数字增加或减少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
之类的字符串或条件。
我需要以更好的方式,更专业地重写此功能,并按所述方式工作。
谢谢。
答案 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为基础,建议您将plus
和minus
的常量分别定义为+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 == 0
和n % 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);
}