Мне нужно извлечь каждый n-й символ строки в Javascript - PullRequest
0 голосов
/ 07 февраля 2019

Я читаю все онлайн, но это не совсем то, что мне нужно

var x = 'a1b2c3d4e5'

Мне нужно что-то, чтобы я набрал

, используя 1 ответ должен быть abcde, используя 2 ответдолжно быть 12345 с использованием 3, ответ должен быть b3e

идея, лежащая в основе, если использовать 1, то захватывает 1 пропуск 1 идея, стоящая за этим, если использовать 2, это захватывает 2 пропускает 2 идея, стоящая за этим, при использовании 3 захватывает 3 пропускает 3

Я не хочу использовать цикл for, так как это долгий путь, особенно когда ваш xбольше 300000 символов.

есть ли регулярное выражение, которое я могу использовать, или функция, о которой я не знаю?

update

I'mпытаюсь кое-как реализовать ваши ответы, но когда я использую 1, вот когда я сталкиваюсь с проблемой.Я упоминал, что пытался держаться подальше от циклов for, потому что ресурсы на сервере.Чем больше клиентов подключаются, тем медленнее становится все.Пока что array.filter выглядит намного быстрее.

Как только я его найду, я приму ответ.

Ответы [ 4 ]

0 голосов
/ 07 февраля 2019

То, что я бы предложил, чтобы избежать перебора всего массива, это перейти прямо к известным nth.

Вот пара вариантов:

function nthCharSubstr(str, nth) {
    let res = "";
    for (let i = nth - 1; i < str.length; i += nth) {
        res += string[i];
    }
    return res;
}

Подробнее ES6-y:

const nthCharSubstr = (str, nth) =>
    [...Array(parseInt(str.length / nth)).keys()] // find out the resulting number of characters and create and array with the exact length
        .map(i => nth + i * nth - 1)              // each item in the array now represents the resulting character's index
        .reduce((res, i) => res + str[i], "");    // pull out each exact character and group them in a final string

В этом решении этот комментарий считается действительным.

0 голосов
/ 07 февраля 2019

Так как я не эксперт по регулярным выражениям, я бы использовал некоторые необычные функции es6 для фильтрации ваших символов.

var x = 'a1b2c3d4e5'
var n = 2;

var result = [...x].filter((char, index) => index % n == 0);

console.log(result);

Обратите внимание, что поскольку 0 % 2 также возвращает 0, это всегда возвращает первый символ.Вы можете отфильтровать первый символ, добавив еще одну простую проверку.

var result = [...x].filter((char, index) => index > 0 && index % n == 0);

0 голосов
/ 07 февраля 2019

Как вариант:

function getNth(str, nth) {
  return [...str].filter((_, i) => (i + 1) % nth === 0).join('');
}

console.log(getNth('a1b2c3d4e5', 2)); // 12345

console.log(getNth('a1b2c3d4e5', 3)); // b3e
0 голосов
/ 07 февраля 2019

Как отмечают другие, регулярные выражения не похожи на магию;там все еще будет механизм зацикливания.Не беспокойтесь, когда дело доходит до циклов, 300 000 - это ничто -

console.time('while')

let x = 0

while (x++ < 300000)
  x += 1
  
console.timeEnd('while')
// while: 5.135 ms

console.log(x)
// 300000

Сделайте большую строку, кого это волнует?300 000 - это ничто -

// 10 chars repeated 30,000 times
const s =
  'abcdefghij'.repeat(30000) 

console.time('while string')

let x = 0
let interval = 2
let values = []
while (x < s.length)
{ values.push(s[x])
  x += interval
}

let result = values.join('')

console.timeEnd('while string')
// while string: 31.990ms

console.log(result)
console.log(result.length)
// acegiacegiacegiacegiacegiacegiacegiacegia...
// 150000

Или используйте интервал 3 -

const s =
  'abcdefghij'.repeat(30000) 

console.time('while string')

let x = 0
let interval = 3
let values = []
while (x < s.length)
{ values.push(s[x])
  x += interval
}

let result = values.join('')

console.timeEnd('while string')
// while string: 25.055ms

console.log(result)
console.log(result.length)
// adgjcfibehadgjcfibehadgjcfibehadgjcfibe...
// 100000

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

const s =
  'abcdefghij'.repeat(30000) 

console.time('while string')

let x = 0
let interval = 25 // big interval
let values = []
while (x < s.length)
{ values.push(s[x])
  x += interval
}

let result = values.join('')

console.timeEnd('while string')
// while string: 6.130

console.log(result)
console.log(result.length)
// afafafafafafafafafafafafafafafafafafafafafafa...
// 12000

Вы можете достичь функционального стиля и безопасной скорости стека одновременно -

const { loop, recur } = require('./lib')

const everyNth = (s, n) =>
  loop
    ( (acc = '', x = 0) =>
        x >= s.length
          ? acc
          : recur(acc + s[x], x + n)
    )

const s = 'abcdefghij'.repeat(30000)

console.time('loop/recur')
const result = everyNth(s, 2)
console.timeEnd('loop/recur')
// loop/recur: 31.615 ms

console.log(result)
console.log(result.length)
// acegiacegiacegiacegiacegiacegiacegia ...
// 150000

Оба легко реализуются -

const recur = (...values) =>
  ({ recur, values })

const loop = f =>
{ let acc = f()
  while (acc && acc.recur === recur)
    acc = f(...acc.values)
  return acc
}

// ...

module.exports =
  { loop, recur, ... }

И в отличие от [...str].filter(...) решений, которые всегда будут проходить через каждый элемент, наш пользовательский loop гораздо более гибок и получает преимущество в скорости при использовании более высокого интервала n -

console.time('loop/recur')
const result = everyNth(s, 25)
console.timeEnd('loop/recur')
// loop/recur: 5.770ms

console.log(result)
console.log(result.length)
// afafafafafafafafafafafafafafa...
// 12000

const recur = (...values) =>
  ({ recur, values })
  
const loop = f =>
{ let acc = f()
  while (acc && acc.recur === recur)
    acc = f(...acc.values)
  return acc
}

const everyNth = (s, n) =>
  loop
    ( (acc = '', x = 0) =>
        x >= s.length
          ? acc
          : recur(acc + s[x], x + n)
    )

const s = 'abcdefghij'.repeat(30000)

console.time('loop/recur')
const result = everyNth(s, 2)
console.timeEnd('loop/recur')
// loop/recur: 31.615 ms

console.log(result)
console.log(result.length)
// acegiacegiacegiacegiacegiacegiacegia ...
// 150000
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...