You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
-For each item we'll check if the resulting array already has that item.
3
-
-If it is so, then ignore, otherwise add to results.
1
+
Давайте пройдёмся по элементам массива:
2
+
-Для каждого элемента мы проверим, есть ли в массиве с результатом этот элемент.
3
+
-Если есть, то игнорируем его, а если нет добавляем к результатам.
4
4
5
5
```js run demo
6
6
functionunique(arr) {
@@ -15,25 +15,25 @@ function unique(arr) {
15
15
return result;
16
16
}
17
17
18
-
let strings = ["Hare", "Krishna", "Hare", "Krishna",
19
-
"Krishna", "Krishna", "Hare", "Hare", ":-O"
18
+
let strings = ["кришна", "кришна", "харе", "харе",
19
+
"харе", "харе", "кришна", "кришна", ":-O"
20
20
];
21
21
22
-
alert( unique(strings) ); //Hare, Krishna, :-O
22
+
alert( unique(strings) ); //кришна, харе, :-O
23
23
```
24
24
25
-
The code works, but there's a potential performance problem in it.
25
+
Код работает, но в нём есть потенциальная проблемма с производительностью.
26
26
27
-
The method `result.includes(str)`internally walks the array`result`and compares each element against`str` to find the match.
27
+
Метод `result.includes(str)`внутри себя обходит массив`result`и сравнивает каждый элемент с`str`, чтобы найти совпадение.
28
28
29
-
So if there are `100`elements in `result` and no one matches`str`, then it will walk the whole `result`and do exactly`100`comparisons. And if`result`is large, like `10000`, then there would be `10000`comparisons.
29
+
Таким образом, если `result` содержит `100`элементов и ни один не сопоставляет со`str`, тогда он обойдёт весь `result`и сделает ровно`100`сравнений. А если`result`большой, например, `10000`, то будет произведено `10000`сравнений.
30
30
31
-
That's not a problem by itself, because JavaScript engines are very fast, so walk`10000`array is a matter of microseconds.
31
+
Само по себе это не проблема, потому что движки JavaScript очень быстрые, поэтому обход`10000`элементов массива занимает считанные микросекунды.
32
32
33
-
But we do such test for each element of `arr`, in the`for` loop.
33
+
Но мы делаем такую проверку для каждого элемента `arr` в цикле`for`.
34
34
35
-
So if`arr.length`is`10000` we'll have something like `10000*10000` = 100 millions of comparisons. That's a lot.
35
+
Поэтому, если`arr.length`равен`10000`, у нас будет что-то вроде `10000*10000` = 100 миллионов сравнений. Это многовато.
36
36
37
-
So the solution is only good for small arrays.
37
+
Вот почему данное решение подходит только для небольших массивов.
38
38
39
-
Further in the chapter <info:map-set-weakmap-weakset>we'll see how to optimize it.
39
+
Далее в главе <info:map-set-weakmap-weakset>мы увидим, как его оптимизировать.
Copy file name to clipboardExpand all lines: 1-js/05-data-types/05-array-methods/9-shuffle/solution.md
+19-19Lines changed: 19 additions & 19 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,4 +1,4 @@
1
-
The simple solution could be:
1
+
Простое решение может быть:
2
2
3
3
```js run
4
4
*!*
@@ -12,18 +12,18 @@ shuffle(arr);
12
12
alert(arr);
13
13
```
14
14
15
-
That somewhat works, because`Math.random() - 0.5`is a random number that may be positive or negative, so the sorting function reorders elements randomly.
15
+
Это конечно будет работать потому, что`Math.random() - 0.5`отдаёт случайное число, которое может быть положительным или отрицательным, следовательно функция сортировки меняет порядок элементов случайным образом.
16
16
17
-
But because the sorting function is not meant to be used this way, not all permutations have the same probability.
17
+
Но поскольку метод `sort` не предназначен для использования в таких случаях, не все возможные варианты имеют одинаковую вероятность.
18
18
19
-
For instance, consider the code below. It runs`shuffle` 1000000 times and counts appearances of all possible results:
19
+
Например, рассмотрим код ниже. Он запускает`shuffle` 1000000 раз и считает вероятность появления для всех возможных вариантов `arr`:
20
20
21
21
```js run
22
22
functionshuffle(array) {
23
23
array.sort(() =>Math.random() -0.5);
24
24
}
25
25
26
-
//counts of appearances for all possible permutations
26
+
//подсчёт вероятности для всех возможных вариантов
27
27
let count = {
28
28
'123':0,
29
29
'132':0,
@@ -39,13 +39,13 @@ for (let i = 0; i < 1000000; i++) {
39
39
count[array.join('')]++;
40
40
}
41
41
42
-
//show counts of all possible permutations
42
+
//показать количество всех возможных вариантов
43
43
for (let key in count) {
44
44
alert(`${key}: ${count[key]}`);
45
45
}
46
46
```
47
47
48
-
An example result (for V8, July 2017):
48
+
Результат примера (для V8, июль 2017):
49
49
50
50
```js
51
51
123:250706
@@ -56,24 +56,24 @@ An example result (for V8, July 2017):
56
56
321:125223
57
57
```
58
58
59
-
We can see the bias clearly: `123`and`213`appear much more often than others.
59
+
Теперь мы отчётливо видим допущенное отклонение: `123`и`213`появляются намного чаще чем остальные варианты.
60
60
61
-
The result of the code may vary between JavaScript engines, but we can already see that the approach is unreliable.
61
+
Результаты этого кода могут варьироваться при запуске на разных движках JavaScript, но очевидно что такой подход не надёжен.
62
62
63
-
Why it doesn't work? Generally speaking, `sort`is a "black box": we throw an array and a comparison function into it and expect the array to be sorted. But due to the utter randomness of the comparison the black box goes mad, and how exactly it goes mad depends on the concrete implementation that differs between engines.
63
+
Так почему это не работает? Если говорить простыми словами, то `sort`это "чёрный ящик": мы бросаем в него массив и функцию сравнения ожидая получить отсортированный массив. Но из-за абсолютной хаотичности сравнений чёрный ящик сходит с ума, и как именно он сходит с ума, зависит от конкретной его реализации, которая различна на разных движках JavaScript.
64
64
65
-
There are other good ways to do the task. For instance, there's a great algorithm called [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle). The idea is to walk the array in the reverse order and swap each element with a random one before it:
65
+
Есть и другие хорошие способы решить эту задачу. Например, есть отличный алгоритм под названием [Тасование Фишера — Йетса](https://ru.wikipedia.org/wiki/%D0%A2%D0%B0%D1%81%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%A4%D0%B8%D1%88%D0%B5%D1%80%D0%B0_%E2%80%94_%D0%99%D0%B5%D1%82%D1%81%D0%B0). Суть заключается в том, чтобы проходить по массиву в обратном порядке и менять местами каждый элемент со случайным элементом, который находится перед ним.
66
66
67
67
```js
68
68
functionshuffle(array) {
69
69
for (let i =array.length-1; i >0; i--) {
70
-
let j =Math.floor(Math.random() * (i +1)); //random index from 0 to i
71
-
[array[i], array[j]] = [array[j], array[i]]; //swap elements
70
+
let j =Math.floor(Math.random() * (i +1)); //случайный индекс от 0 до i
71
+
[array[i], array[j]] = [array[j], array[i]]; //перестановка элементов
72
72
}
73
73
}
74
74
```
75
75
76
-
Let's test it the same way:
76
+
Давайте проверим эту реализацию на том же примере:
77
77
78
78
```js run
79
79
functionshuffle(array) {
@@ -83,7 +83,7 @@ function shuffle(array) {
83
83
}
84
84
}
85
85
86
-
//counts of appearances for all possible permutations
86
+
//подсчёт вероятности для всех возможных вариантов
87
87
let count = {
88
88
'123':0,
89
89
'132':0,
@@ -99,13 +99,13 @@ for (let i = 0; i < 1000000; i++) {
99
99
count[array.join('')]++;
100
100
}
101
101
102
-
//show counts of all possible permutations
102
+
//показать количество всех возможных вариантов
103
103
for (let key in count) {
104
104
alert(`${key}: ${count[key]}`);
105
105
}
106
106
```
107
107
108
-
The example output:
108
+
Пример вывода:
109
109
110
110
```js
111
111
123:166693
@@ -116,6 +116,6 @@ The example output:
116
116
321:166316
117
117
```
118
118
119
-
Looks good now: all permutations appear with the same probability.
119
+
Теперь всё в порядке: все варианты появляются с одинаковой вероятностью.
120
120
121
-
Also, performance-wise the Fisher-Yates algorithm is much better, there's no "sorting" overhead.
121
+
Кроме того, если посмотреть с точки зрения производительности, то алгоритм "Тасование Фишера — Йетса" намного быстрее, так как в нём нет лишних затрат на сортировку.
0 commit comments