Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Преобразование числа в строку (https://javascript.ru/forum/misc/81010-preobrazovanie-chisla-v-stroku.html)

Alena_03 13.09.2020 16:36

Преобразование числа в строку
 
Всем привет, задание: Дан массив числами, например: [10, 20, 30, 50, 235, 3000]. Выведите на экран только те числа из
массива, которые начинаются на цифру 1, 2 или 5. Нужно сделать через преобразование числа в строку, но выводит что-то непонятное. Мой код:
var arr = [10, 20, 30, 50, 235, 3000];
arr = String (arr);
for (var i = 0; i < arr.length; i++) {
if (arr[i][0] == 1 || arr[i][0] == 2 || arr[i][0] == 5) {
document.write(arr[i] + '<br>');
}
}
Не пойму, что не нравится, помогите. Или есть какой-нибудь другой способ? :help:

Nexus 13.09.2020 16:47

var numbers = [10, 20, 30, 50, 235, 3000];
var result = numbers.filter(num => [1, 2, 5].includes(+String(num).charAt(0)));

alert(result.join('; '));

Alena_03 13.09.2020 16:53

Nexus, спасибо ещё раз огромное)

Семён Дементьев 16.05.2021 22:59

a = [10, 20, 30, 50, 235, 3000];

for(i=0; i<a.length; i++){
b = String(a[i]); // приобразовали в строку КАЖДЫЙ элемент

if(b[0]==1 || b[0]==2 || b[0]==5) // спрашиваем, ПЕРВЫЙ символ элемента = 1 или 2 или 5?
{
console.log(a[i]); // выводим тот элемент который верен по условию
}
}

ksa 17.05.2021 08:47

Семён Дементьев, нет особого смысла в выкладывании варианта хуже предыдущего... :no:

Например такой пример
var numbers = [10, 20, 30, 50, 235, 3000];
var result = numbers.filter(num => /^[125]/.test(num));

alert(result.join('; '));


Хотя бы короче предыдущего... ;)

voraa 17.05.2021 09:43

Цитата:

Сообщение от ksa
нет особого смысла в выкладывании варианта хуже предыдущего...

Хуже или лучше - понятие относительное

<script>
let t0, t1, t2, t3;
const ar = Array.from({length:1_000_000}, (_, i)=>i)
let b;

t0 = performance.now();
b = ar.filter(num => [1, 2, 5].includes(+String(num).charAt(0)));
t1 = performance.now() - t0;

t0 = performance.now();
b=[];
for(let i=0; i<ar.length; i++){
	const as = String(ar[i])[0]; 
	if(as === '1' || as === '2' || as === '5') b.push(ar[i])
}
t2 = performance.now() - t0;

t0 = performance.now();
b = ar.filter(num => /^[125]/.test(num));
t3 = performance.now() - t0;

alert (`t1=${t1} t2=${t2} t3=${t3}`)
</script>


Второй вариант самый быстрый, а третий - самый медленный
(ну у меня в Chrome так)

рони 17.05.2021 10:33

Цитата:

Сообщение от voraa
Второй вариант самый быстрый,

:yes: для "классики" не хватает длину массива закешировать.

voraa 17.05.2021 11:19

Ну как бы разработчики V8 часто очень гордятся, что путем различных ухищрений им удается поднять производительность на 5-10%
А тут порядка 20-25% и совершенно бесплатно.

ksa 17.05.2021 11:45

Цитата:

Сообщение от voraa
Второй вариант самый быстрый, а третий - самый медленный

Второй вариант создает дополнительный массив (это я про "оригинал")... :)

voraa 17.05.2021 12:01

Цитата:

Сообщение от ksa
Второй вариант создает дополнительный массив

Какой?

ksa 17.05.2021 12:11

voraa, оригинальный
https://javascript.ru/forum/misc/810...tml#post536666

Не твоя модификация.

voraa 17.05.2021 12:29

Я про него и спрашиваю.
Не вижу я там никакого массива.
Там всего 3 переменные используются a - исходный массив, b - строка, ну и i.

ksa 17.05.2021 12:33

Цитата:

Сообщение от voraa
Не вижу я там никакого массива.

Это меня уже глаза подводят... :(

Vlasenko Fedor 17.05.2021 12:33

const ar = Array.from({length: 1_000_000}, (_, i) => i)
let b;

console.time('V1');
b = ar.filter(num => [1, 2, 5].includes(+String(num).charAt(0)));
console.timeEnd('V1');

b = [];
console.time('V2');
for (let i = 0; i < ar.length; i++) {
    const as = String(ar[i])[0];
    if (as === '1' || as === '2' || as === '5') b.push(ar[i])
}
console.timeEnd('V2');
console.time('V3');
b = ar.filter(num => /^[125]/.test(num));
console.timeEnd('V3');
b = [];
const getFirstNumber = num => {
    num = num / 10 | 0;
    return num > 9 ? getFirstNumber(num) : num;
}
console.time('V4');
for (let i = 0; i < ar.length; i++) {
    let f = getFirstNumber(ar[i]);
    if (f === 1 || f === 2 || f === 5) b.push(ar[i])
}
console.timeEnd('V4');

Вариант 4 здесь показывает скорость без преобразования в строку
Для чисел с которыми работает js NodeJs среда

ksa 17.05.2021 12:38

Чем мне всегда нравилось здешнее сообщество - так это предоставляемые возможности, казалось бы на простых вопросах. :thanks:

voraa 17.05.2021 13:15

Цитата:

Сообщение от Vlasenko Fedor
Вариант 4 здесь показывает скорость без преобразования в строку
Для чисел с которыми работает js NodeJs среда

Ну только строка 26 должна быть так
if (f === 1 || f === 2 || f === 5) b.push(ar[i])
А то массив b пустым получается

Это интересно. Даже несмотря на рекурсию этот вариант гораздо быстрее, чем преобразование в строку.
Видимо при таком количестве вызовов эта функция хорошо оптимизируется в ассемблерный код.

Но это в Хроме. Файрфокс не показывает таких хороших результатов. Там второй вариант все равно быстрее.

Vlasenko Fedor 17.05.2021 13:51

Без рекурсии в 8-10 раз быстрее в node
const ar = Array.from({length: 1_000_000}, (_, i) => i)
let b;

console.time('V1');
b = ar.filter(num => [1, 2, 5].includes(+String(num).charAt(0)));
console.timeEnd('V1');

b = [];
console.time('V2');
for (let i = 0; i < ar.length; i++) {
    const as = String(ar[i])[0];
    if (as === '1' || as === '2' || as === '5') b.push(ar[i])
}
console.timeEnd('V2');
console.time('V3');
b = ar.filter(num => /^[125]/.test(num));
console.timeEnd('V3');
b = [];
const getFirstNumber = num => {
    while (num > 9) num = num / 10 | 0;
    return num;
}
console.time('V4');
for (let i = 0; i < ar.length; i++) {
    let f = getFirstNumber(ar[i]);
    if (f === 1 || f === 2 || f === 5) b.push(ar[i])
}
console.timeEnd('V4');

и в браузерах уже V4 впереди планеты


Часовой пояс GMT +3, время: 15:54.