Javascript循环行为

Javascript循环行为,javascript,arrays,loops,theory,Javascript,Arrays,Loops,Theory,alltones数组包含音乐音阶中所有可能的音符 var alltones = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" ]; 我想获取用户输入的音调,然后构造一个包含数组某些元素的列表 假设我从alltones[5]或“F”开始,并希望从该点开始获取数组的每一个第二个元素,并将其放入我的列表中,直到回到“F”。数组更像一个圆形而不是直线列表。当循环到达最后一个元素时,我有点不确定数组是如何运行的 我是否通

alltones
数组包含音乐音阶中所有可能的音符

var alltones = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" ];
我想获取用户输入的音调,然后构造一个包含数组某些元素的列表

假设我从
alltones[5]
“F”
开始,并希望从该点开始获取数组的每一个第二个元素,并将其放入我的列表中,直到回到
“F”
。数组更像一个圆形而不是直线列表。当循环到达最后一个元素时,我有点不确定数组是如何运行的

我是否通过基于用户输入生成新数组来解决问题。或者JavaScript有没有一种方法可以在数组到达末尾时循环回数组的开头,从而将数组视为一个圆

例如: 用户输入=F
我正在寻找的输出是从F开始计数(每两项),直到我们回到数组中的F

因此,所需的输出将是=>F G A B C#D#

您可以在两个循环中完成,因为JS没有内置的对圆的支持

for (var i = users_input; i < alltones.length; i += 1) {
  ... use alltones[i] for calc
}
for (var i = 0; i < users_input; i += 1) {
  ... use alltones[i] for calc
}
for(var i=users\u input;i
或者类似的东西。 确实不需要创建新阵列。

这样做怎么样:

function getNotes(index) {
  var list = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" ];
  return list.splice(index).concat(list).filter(function(note, i) {
    return i % 2 == 0;
  });
}
getNotes(3); // ["D#", "F", "G", "A", "B", "C#"]
这样做的目的是首先重新组织数组,以便将选定的索引移到开头,并将之前的所有内容移到结尾,然后过滤掉所有其他注释。如果希望让
getNotes
函数使用字符串,可以使用
indexOf
方法
indexOf
filter
(上面使用)是ECMAScript 5的一部分,因此您可能需要多填充,具体取决于您计划支持的浏览器

这里有一个。

没有一个可以做你想做的事情,但是可以使用和轻松定义一个:

然后您可以使用
lcycle
rcycle
作为常规数组方法:

>>> alltones.lcycle(3)
[ "D#" , "E" , "F" , "F#" , "G" , "G#" , "A" , "A#" , "B" , "C" , "C#" , "D" ]
>>> alltones.rcycle(4)
[ "G#" , "A" , "A#" , "B" , "C" , "C#" , "D" , "D#" , "E" , "F" , "F#" , "G" ]
>>> alltones.lcycle_m(3)
>>> alltones
[ "D#" , "E" , "F" , "F#" , "G" , "G#" , "A" , "A#" , "B" , "C" , "C#" , "D" ]
>>> alltones.rcycle_m(3)
>>> alltones
[ "C" , "C#" , "D" , "D#" , "E" , "F" , "F#" , "G" , "G#" , "A" , "A#" , "B" ]
请注意,这两个方法都返回一个新数组。如果您想改变原始数组,可以使用定义类似的方法

同样,您可以使用
lcycle\u m
rcycle\u m
作为常规数组方法:

>>> alltones.lcycle(3)
[ "D#" , "E" , "F" , "F#" , "G" , "G#" , "A" , "A#" , "B" , "C" , "C#" , "D" ]
>>> alltones.rcycle(4)
[ "G#" , "A" , "A#" , "B" , "C" , "C#" , "D" , "D#" , "E" , "F" , "F#" , "G" ]
>>> alltones.lcycle_m(3)
>>> alltones
[ "D#" , "E" , "F" , "F#" , "G" , "G#" , "A" , "A#" , "B" , "C" , "C#" , "D" ]
>>> alltones.rcycle_m(3)
>>> alltones
[ "C" , "C#" , "D" , "D#" , "E" , "F" , "F#" , "G" , "G#" , "A" , "A#" , "B" ]

在两个循环中执行此操作,一个用于从起始点开始的数组成员,另一个用于从起始点开始的数组成员,这是一种更好的方法;这里的关键是从头开始,这取决于我们在数组末尾的结束位置

您可以创建一个通用函数,如

  var alltones = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" ];

  function build_tones(arr, start, jump_by){

  var new_list = [];

           //finish first iteration and get the last index so that we can offset accordingly from the beginning
             var get_last = (function(){
               var last;
              for(i = start; i <= arr.length; i+=jump_by){
                new_list.push(arr[i]);
                last = i;
                }
              return last;
              })();

     //do the second iteration by picking up from the index left and continue from first

    for(i = 0 + arr.length%get_last; i < start; i+=jump_by){
    new_list.push(arr[i]);
    }

    return new_list;

  }

 var result = build_tones(alltones, 5, 2);
 console.log(result);
var alltones=[“C”、“C”、“D”、“D”、“E”、“F”、“F”、“G”、“G”、“A”、“A”、“B”];
功能构建音调(arr、启动、跳转){
var新_列表=[];
//完成第一次迭代并获得最后一个索引,这样我们就可以从一开始就进行相应的偏移
var get_last=(函数(){
var last;

对于(i=start;i,以下是一种在数组到达末尾时循环回数组开头的方法:

arr[index%arr.length]
,如果
index
arr.length
,它将“循环”到起点

这项技术效率很高,几乎适用于所有语言

var alltones = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" ];

function generateMusic(startIndex) {
    var i = 0, music = [],
        tonesCount = alltones.length

    do { 
        music.push(alltones[(startIndex+i)%tonesCount]); 
    } while ((i+=2) < tonesCount);

    return music;
}

也许模索引是您想要的-类似于
alltones[x%alltones.length]
听起来您可以使用slice和array.indexOf和concat创建一个新的数组。在记录之前,请向我们展示一些示例运行(输入和预期输出)你在寻找什么?这是确定你真正想要做什么所需要的。+1很好的解决方案,但我很惊讶你没有把第二个
返回
放在同一行;)我想这只是个人喜好。我觉得它更具可读性;我总是为函数体添加换行和缩进。我的评论显然是一次失败的讽刺尝试;)真的很有趣。从来没有想到过。也谢谢你的提琴示例!听起来太复杂了。想象一个非常复杂的循环体或一个循环
(var i=0;i
对于复杂的循环体,您可以将登录名移动到函数中,并使用参数调用。单循环听起来不错,我会将其复制到toolboxOld帖子中……但这是一个非常好的答案。我从未考虑过以这种方式扩展阵列原型。
console.log(generateMusic(3)); //["D#", "F", "G", "A", "B", "C#"]
console.log(generateMusic(5)); //["F", "G", "A", "B", "C#", "D#"]