renovations
This commit is contained in:
parent
4b8b168fd2
commit
c7d4c7e3ff
172 changed files with 869 additions and 244 deletions
|
@ -0,0 +1,10 @@
|
|||
function unique(arr) {
|
||||
var obj = {};
|
||||
|
||||
for(var i=0; i<arr.length; i++) {
|
||||
var str = arr[i];
|
||||
obj[str] = true; // запомнить строку в виде свойства объекта
|
||||
}
|
||||
|
||||
return Object.keys(obj); // или собрать ключи перебором для IE<9
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
describe("unique", function() {
|
||||
it("убирает неуникальные элементы из массива", function() {
|
||||
var strings = ["кришна", "кришна", "харе", "харе",
|
||||
"харе", "харе", "кришна", "кришна", "8-()"];
|
||||
|
||||
assert.deepEqual( unique(strings), ["кришна", "харе", "8-()"] );
|
||||
});
|
||||
|
||||
it("не изменяет исходный массив", function() {
|
||||
var strings = ["кришна", "кришна", "харе", "харе"];
|
||||
unique(strings);
|
||||
assert.deepEqual( strings, ["кришна", "кришна", "харе", "харе"] );
|
||||
});
|
||||
});
|
|
@ -0,0 +1,81 @@
|
|||
# Решение перебором (медленное)
|
||||
|
||||
Пройдём по массиву вложенным циклом.
|
||||
|
||||
Для каждого элемента мы будем искать, был ли такой уже. Если был -- игнорировать:
|
||||
|
||||
```js
|
||||
//+ run
|
||||
function unique(arr) {
|
||||
var obj = {};
|
||||
var result = [];
|
||||
|
||||
nextInput:
|
||||
for(var i=0; i<arr.length; i++) {
|
||||
var str = arr[i]; // для каждого элемента
|
||||
for(var j=0; j<result.length; j++) { // ищем, был ли он уже?
|
||||
if (result[j] == str) continue nextInput; // если да, то следующий
|
||||
}
|
||||
result.push(str);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
var strings = ["кришна", "кришна", "харе", "харе",
|
||||
"харе", "харе", "кришна", "кришна", "8-()"];
|
||||
|
||||
alert( unique(strings) ); // кришна, харе, 8-()
|
||||
```
|
||||
|
||||
Давайте посмотрим, насколько быстро он будет работать.
|
||||
|
||||
Предположим, в массиве `100` элементов. Если все они одинаковые, то `result` будет состоять из одного элемента и вложенный цикл будет выполняться сразу. В этом случае всё хорошо.
|
||||
|
||||
А если все, или почти все элементы разные?
|
||||
|
||||
В этом случае для каждого элемента понадобится обойти весь текущий массив результатов, после чего -- добавить в этот массив.
|
||||
|
||||
<ol>
|
||||
<li>Для первого элемента -- это обойдётся в `0` операций доступа к элементам `result` (он пока пустой).</li>
|
||||
<li>Для второго элемента -- это обойдётся в `1` операцию доступа к элементам `result`.</li>
|
||||
<li>Для третьего элемента -- это обойдётся в `2` операции доступа к элементам `result`.</li>
|
||||
<li>...Для n-го элемента -- это обойдётся в `n-1` операций доступа к элементам `result`.</li>
|
||||
</ul>
|
||||
|
||||
Всего <code>0 + 1 + 2 + ... + n-1 = (n-1)*n/2 = n<sup>2</sup>/2 - n/2</code> (как сумма арифметической прогрессии), то есть количество операций растёт примерно как квадрат от `n`.
|
||||
|
||||
Это очень быстрый рост. Для `100` элементов -- `4950` операций, для `1000` -- `499500` (по формуле выше).
|
||||
|
||||
Поэтому такое решение подойдёт только для небольших массивов. Вместо вложенного `for` можно использовать и `arr.indexOf`, ситуация от этого не поменяется, так как `indexOf` тоже ищет перебором.
|
||||
|
||||
# Решение с объектом (быстрое)
|
||||
|
||||
Наилучшая техника для выбора уникальных строк -- использование вспомогательного объекта. Ведь название свойства в объекте, с одной стороны -- строка, а с другой -- всегда уникально. Повторная запись в свойство с тем же именем перезапишет его.
|
||||
|
||||
Например, если `"харе"` попало в объект один раз (`obj["харе"] = true`), то второе такое же присваивание ничего не изменит.
|
||||
|
||||
Решение ниже создаёт объект `obj = {}` и записывает в него все строки как имена свойств. А затем собирает свойства из объекта в массив через `for..in`. Дубликатов уже не будет.
|
||||
|
||||
```js
|
||||
//+ run
|
||||
function unique(arr) {
|
||||
var obj = {};
|
||||
|
||||
for(var i=0; i<arr.length; i++) {
|
||||
var str = arr[i];
|
||||
*!*
|
||||
obj[str] = true; // запомнить строку в виде свойства объекта
|
||||
*/!*
|
||||
}
|
||||
|
||||
return Object.keys(obj); // или собрать ключи перебором для IE8-
|
||||
}
|
||||
|
||||
var strings = ["кришна", "кришна", "харе", "харе",
|
||||
"харе", "харе", "кришна", "кришна", "8-()"];
|
||||
|
||||
alert( unique(strings) ); // кришна, харе, 8-()
|
||||
```
|
||||
|
||||
Так что можно положить все значения как ключи в объект, а потом достать.
|
|
@ -0,0 +1,21 @@
|
|||
# Оставить уникальные элементы массива
|
||||
|
||||
[importance 3]
|
||||
|
||||
Пусть `arr` -- массив строк.
|
||||
|
||||
Напишите функцию `unique(arr)`, которая возвращает массив, содержащий только уникальные элементы `arr`.
|
||||
|
||||
Например:
|
||||
|
||||
```js
|
||||
function unique(arr) {
|
||||
/* ваш код */
|
||||
}
|
||||
|
||||
var strings = ["кришна", "кришна", "харе", "харе",
|
||||
"харе", "харе", "кришна", "кришна", "8-()"];
|
||||
|
||||
alert( unique(strings) ); // кришна, харе, 8-()
|
||||
```
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue