Array splice

The Exercise: Building a (Soundless) Drum Machine

Here is a wireframe of an example interface.

You can build your app to look like this wireframe. If you’re someone who loves css and beautifying the UI, show us that. Approach this task as your way of displaying your
favorite parts of frontend development.

READ THIS IT IS REALLY IMPORTANT:
This drumkit does NOT NEED TO PLAY SOUND. Instead we want to see a real time VISUAL representation of the sequence being played.

REQUIRED FEATURES

Your drum machine should include the following features:

  • Play & stop controls.
  • The ability for the user to alter the tempo of the sequence. This tempo change can occur while the song is stopped or playing – whatever makes the most sense for your code structure.
  • Playback readout — there should be a visual indication of the active step while the sequence is playing. Ideally, the playback speed will also match the
    sequence tempo.
  • There should be 3 premade drum pattern sequences that can be loaded into your drumkit. The UI element is up to you; in the wireframe it is the dropdown.
  • The pattern is expected to be 8 steps or more. eg- if you look at that wireframe, there are 16 columns.
  • The time signature is expected to be 4/4 (if you don’t know what that is, don’t worry and ignore this instruction).

Useful Timing Info

At a 4/4 time signature of 60 BPM (beats per minute), we get 1 beat per second.
We can assume that 8 steps = 1 bar, representing 4 beats.
In other words, a 8 step pattern would take seconds to play and each step would take seconds.

Extra mile

If you have done all the required features and want to keep going because you just made a cool drumkit, try doing the following:

  • Output sound — you might want to look at some higher-level libraries that allow you to load and play sounds rather than getting mired in the details of managing and playing the sounds directly (though you’re certainly welcome to do that too).
  • Try mix and matching patterns of different durations (8, 16, 32 steps),
    note that if you have 2 patterns, one 8 and one 16, the 8 should play
    twice while the 16 plays once.
  • Add support for velocity (the amplitude/volume of a note).
  • You don’t have to limit yourself to the features/layout/parts on the diagram. Take inspiration from existing drum machines and feel free to get creative!

What can I use & are we looking for?

  • Use the tools you are comfortable with! You can use any framework. You can use plugins & libraries. You can write this entirely in vanilla JS. Want to use canvas? Go for it.
  • Please include a readme. If we need to run the code locally to see it work, please give us instructions.
  • Please use this exercise as a way to show us what you like about Frontend Development. Some people live for performance, others for a11y, or great UX or writing tests. We are aware of the time constraint, if what you love takes time, put comments in.

Splice Evaluation

If you are given this exercise as a code challenge, we are going to
discuss a few things with you. In order to help you prepare, here is a
list of various specific parts and general aspects of programming we are
interested in discussing:

  • How much time did you spend on the exercise, what parts took longer?
  • What were the hard parts, what parts did you enjoy most?
  • Data modeling — How did you model the concepts of songs and
    tracks/patterns, can you explain why?
  • Simplicity vs Flexibility — How flexible is your solution? Can a user
    define patterns of different lengths? Can they play at the same time?
    Can the patterns be changed in real time? Can the velocity be set?
    None of these features are expected, what is needed for you to add
    support for these?
  • Is your code tested? Why/why not? How would you test it (or test it better)?

Submitting your solution

As soon as you’re ready, send us a link to your repo (either a fork of this repo or a new one that you created). You don’t have to send us the link before you’re ready, but we recommend committing code early and often, with clear descriptive commit messages. This helps us follow your thought process as you build your solution.

Массивы в JavaScript

Сперва нужно разобраться, как работают массивы JavaScript. Как и в других языках программирования, массивы используются для хранения нескольких единиц данных. Разница в том, что массивы JavaScript могут содержать несколько типов данных одновременно.

Чтобы работать с такими массивами, нам понадобятся JavaScript-методы: например, slice () & splice (). Создать массив можно так:

let arrayDefinition = [];   // Array declaration in JS

Теперь создадим другой массив с данными разного типа:

let array = ;

В JavaScript можно создавать массивы с разными типами данных: с числами, строками и логическими значениями.

Удаление элементов

Чтобы удалить элементы, введите элемент, с которого нужно начать (index) и количество элементов, которые нужно удалить (number of elements):

array.splice(index, number of elements);

Параметр Index — это начальная точка удаления элементов. Элементы с порядковым номером меньше заданного параметра Index не будут удалены:

array.splice(2);  // Every element starting from index 2, will be removed

Если не указать второй параметр, все элементы от заданного параметра Index и до конца будут удалены:

only index 0 and 1 are still there

В качестве еще одно примера, я указал 1 в качестве второго параметра: таким образом, каждый раз при повторе метода splice ( ) будет удалять по одному элементу, начиная со второго:

array.splice(2, 1);

Массив до метода splice ( )

Splice ( ) применен один раз:

Элемент 3 удален: следовательно, теперь элемент “hello world” имеет порядковый номер 2

Splice ( ) применен два раза:

На этот раз, был удален элемент “hello world”, потому что его порядковый номер 2

Так можно продолжать до тех пор, пока не останется элементов с порядковым номером 2.

Прокрутка: scrollTo, scrollBy, scrollIntoView

Важно:

Для прокрутки страницы из JavaScript её DOM должен быть полностью построен.

Например, если мы попытаемся прокрутить страницу из скрипта в , это не сработает.

Обычные элементы можно прокручивать, изменяя .

Мы можем сделать то же самое для страницы в целом, используя (кроме основанных на старом WebKit (Safari), где, как сказано выше, ).

Есть и другие способы, в которых подобных несовместимостей нет: специальные методы и .

  • Метод прокручивает страницу относительно её текущего положения. Например, прокручивает страницу на вниз.

    Кнопка ниже демонстрирует это:

    window.scrollBy(0,10)

  • Метод прокручивает страницу на абсолютные координаты . То есть, чтобы левый-верхний угол видимой части страницы имел данные координаты относительно левого верхнего угла документа. Это всё равно, что поставить .
    Для прокрутки в самое начало мы можем использовать .

    window.scrollTo(0,0)

Эти методы одинаково работают для всех браузеров.

JavaScript

JS Array
concat()
constructor
copyWithin()
entries()
every()
fill()
filter()
find()
findIndex()
forEach()
from()
includes()
indexOf()
isArray()
join()
keys()
length
lastIndexOf()
map()
pop()
prototype
push()
reduce()
reduceRight()
reverse()
shift()
slice()
some()
sort()
splice()
toString()
unshift()
valueOf()

JS Boolean
constructor
prototype
toString()
valueOf()

JS Classes
constructor()
extends
static
super

JS Date
constructor
getDate()
getDay()
getFullYear()
getHours()
getMilliseconds()
getMinutes()
getMonth()
getSeconds()
getTime()
getTimezoneOffset()
getUTCDate()
getUTCDay()
getUTCFullYear()
getUTCHours()
getUTCMilliseconds()
getUTCMinutes()
getUTCMonth()
getUTCSeconds()
now()
parse()
prototype
setDate()
setFullYear()
setHours()
setMilliseconds()
setMinutes()
setMonth()
setSeconds()
setTime()
setUTCDate()
setUTCFullYear()
setUTCHours()
setUTCMilliseconds()
setUTCMinutes()
setUTCMonth()
setUTCSeconds()
toDateString()
toISOString()
toJSON()
toLocaleDateString()
toLocaleTimeString()
toLocaleString()
toString()
toTimeString()
toUTCString()
UTC()
valueOf()

JS Error
name
message

JS Global
decodeURI()
decodeURIComponent()
encodeURI()
encodeURIComponent()
escape()
eval()
Infinity
isFinite()
isNaN()
NaN
Number()
parseFloat()
parseInt()
String()
undefined
unescape()

JS JSON
parse()
stringify()

JS Math
abs()
acos()
acosh()
asin()
asinh()
atan()
atan2()
atanh()
cbrt()
ceil()
cos()
cosh()
E
exp()
floor()
LN2
LN10
log()
LOG2E
LOG10E
max()
min()
PI
pow()
random()
round()
sin()
sqrt()
SQRT1_2
SQRT2
tan()
tanh()
trunc()

JS Number
constructor
isFinite()
isInteger()
isNaN()
isSafeInteger()
MAX_VALUE
MIN_VALUE
NEGATIVE_INFINITY
NaN
POSITIVE_INFINITY
prototype
toExponential()
toFixed()
toLocaleString()
toPrecision()
toString()
valueOf()

JS OperatorsJS RegExp
constructor
compile()
exec()
g
global
i
ignoreCase
lastIndex
m
multiline
n+
n*
n?
n{X}
n{X,Y}
n{X,}
n$
^n
?=n
?!n
source
test()
toString()

(x|y)
.
\w
\W
\d
\D
\s
\S
\b
\B
\0
\n
\f
\r
\t
\v
\xxx
\xdd
\uxxxx

JS Statements
break
class
continue
debugger
do…while
for
for…in
for…of
function
if…else
return
switch
throw
try…catch
var
while

JS String
charAt()
charCodeAt()
concat()
constructor
endsWith()
fromCharCode()
includes()
indexOf()
lastIndexOf()
length
localeCompare()
match()
prototype
repeat()
replace()
search()
slice()
split()
startsWith()
substr()
substring()
toLocaleLowerCase()
toLocaleUpperCase()
toLowerCase()
toString()
toUpperCase()
trim()
valueOf()

Добавление элементов

Чтобы добавить элементы с помощью splice ( ), необходимо ввести их в качестве третьего, четвертого и пятого элемента (в зависимости от того, сколько элементов нужно добавить):

array.splice(index, number of elements, element, element);

В качестве примера, добавим элементы a и b в самое начало массива:

array.splice(0, 0, 'a', 'b');

Элементы a и b добавлены в начало массива

Split ( )

Методы Slice( ) и splice( ) используются для массивов. Метод split( ) используется для строк. Он разделяет строку на подстроки и возвращает их в виде массива. У этого метода 2 параметра, и оба из них не обязательно указывать.

string.split(separator, limit);
  • Separator: определяет, как строка будет поделена на подстроки: запятой, знаком и т.д.
  • Limit: ограничивает количество подстрок заданным числом

Метод split( ) не работает напрямую с массивами. Тем не менее, сначала можно преобразовать элементы массива в строки и уже после применить метод split( ).

Давайте посмотрим, как это работает.

Сначала преобразуем массив в строку с помощью метода toString( ):

let myString = array.toString();

Затем разделим строку myString запятыми и ограничим количество подстрок до трех. Затем преобразуем строки в массив:

let newArray = myString.split(",", 3);

В виде массива вернулись первые 3 элемента

Таким образом, элементы массива myString разделены запятыми. Мы поставили ограничение в 3 подстроки, поэтому в качестве массива вернулись первые 3 элемента.

Все символы разделены на подстроки

Real World

You still might be asking yourself if this is worth all the trouble, when one can simply update or access an object directly. One use case that comes to mind is that we can pass a lens function around, enabling to retrieve values from a state object without having to know about how this object is actually structured. Another is that we never directly mutate our object or array but get a shallow copy in return.

Lenses should be used when we need to update or extend an object without wanting to break other implementations or where we don’t have access to libraries like immutable.js f.e.

Using lenses when rendering a view for example, where you need to format the given data, is one good example.

const getComments = view(lensProp('comments'))const getText = view(textLens)const textToUpper = over(textLens, toUpper)const allTextToUpper =  compose(map(compose(getText, textToUpper)), getComments)

Now we can call allTextToUpper which ensures that all are comments are in capital letters minus mutating our original user object.

const renderView = user => (div id="comments">    {map(comment => (div>{comment}div>), allTextToUpper(user))}div>)

Time Expectations

We ask that you set aside about 4 hours to complete the exercise. It’s ok to go over if you’re having fun (drum kits are very fun), but we respect your time. If after 4 hours the exercise is incomplete, share your code and tell us how you would finish it in the form of comments, diagrams, long ramblings with links to things you’re thinking about, or anything that will help us understand how you would troubleshoot your way through a task.

Our engineering team cares about having a good work/life balance. Some of our team have done this exercise recently as part of the hiring process. We empathize with any stress you might be under when looking for a career change. Do your best, let your self come through in your work, and try not to stress out.

Parameter Values

Parameter Description
array Required. Specifies an array
start Required. Numeric value. Specifies where the function will start
removing elements.
0 = the first element.
If this value is set to a negative number, the function will start that far from the last element.
-2 means start at the second last element of the array.
length Optional. Numeric value. Specifies how many elements will
be removed, and also length of the returned array.

If this value is set to a negative number, the function will stop that far from the last element. If this value is not set, the function will
remove all elements, starting from the position set by the start-parameter.

array Optional. Specifies an array with the elements that will be
inserted to the original array. If it’s only one element, it can be a
string, and does not have to be an array.

Запретить прокрутку

Иногда нам нужно сделать документ «непрокручиваемым». Например, при показе большого диалогового окна над документом – чтобы посетитель мог прокручивать это окно, но не документ.

Чтобы запретить прокрутку страницы, достаточно установить .

Попробуйте сами:

Первая кнопка останавливает прокрутку, вторая возобновляет её.

Аналогичным образом мы можем «заморозить» прокрутку для других элементов, а не только для .

Недостатком этого способа является то, что сама полоса прокрутки исчезает. Если она занимала некоторую ширину, то теперь эта ширина освободится, и содержимое страницы расширится, текст «прыгнет», заняв освободившееся место.

Это выглядит немного странно, но это можно обойти, если сравнить до и после остановки, и если увеличится (значит полоса прокрутки исчезла), то добавить в вместо полосы прокрутки, чтобы оставить ширину содержимого прежней.

Ширина/высота окна

Чтобы получить ширину/высоту окна, можно взять свойства из :

Например, эта кнопка показывает высоту вашего окна:

alert(document.documentElement.clientHeight)

Не

Браузеры также поддерживают свойства . Вроде бы, похоже на то, что нам нужно. Почему же не использовать их?

Если есть полоса прокрутки, и она занимает какое-то место, то свойства указывают на ширину/высоту документа без неё (за её вычетом). Иными словами, они возвращают высоту/ширину видимой части документа, доступной для содержимого.

A включают в себя полосу прокрутки.

Если полоса прокрутки занимает некоторое место, то эти две строки выведут разные значения:

В большинстве случаев нам нужна доступная ширина окна: для рисования или позиционирования. Полоса прокрутки «отъедает» её часть. Поэтому следует использовать .

– это важно

Обратите внимание, что геометрические свойства верхнего уровня могут работать немного иначе, если в HTML нет

В современном HTML мы всегда должны указывать .

scrollIntoView

Для полноты картины давайте рассмотрим ещё один метод: elem.scrollIntoView(top).

Вызов прокручивает страницу, чтобы оказался вверху.
У него есть один аргумент:

  • если (по умолчанию), то страница будет прокручена, чтобы появился в верхней части окна. Верхний край элемента совмещён с верхней частью окна.
  • если , то страница будет прокручена, чтобы появился внизу. Нижний край элемента будет совмещён с нижним краем окна.

Кнопка ниже прокрутит страницу так, что она сама окажется вверху:

this.scrollIntoView()

А следующая кнопка прокрутит страницу так, что она сама окажется внизу

this.scrollIntoView(false)

Ссылка на основную публикацию