Эффективный цикл в JavaScript ES6 - PullRequest
0 голосов
/ 19 мая 2019

Я вижу, что в JS есть много способов зацикливания, но я использую стиль PHP, поэтому мой код выглядит так:

let   tickers = ['BTC/USDT','ETH/BTC','CELR/BTC',....] // comes as object from API
const exclude = ['MATIC', 'CELR']
Object.keys(tickers).map(function(key) {
    for (var base in exclude) {
        if ( key.includes(exclude[base]) ) {
            delete tickers[key]
        }
    }
})

ожидаемые тикеры = ['BTC / USDT', 'ETH / BTC', ....]

Код работает, но есть более эффективные способы сделать это в JS?

Ответы [ 4 ]

3 голосов
/ 19 мая 2019

Поскольку у вас есть массивы, есть лучшие способы их итерации, использование объектных методов в массивах довольно неэффективно.Также используя delete вы создаете разреженный массив, который, вероятно, не нужен.Вместо этого вы могли бы просто отфильтровать тикеры, в которые включены некоторые исключения (таким образом, вы также избежите разреженного массива):

  tickers = tickers.filter(ticker => !exclude.some(other => ticker.includes(other)));

Поскольку вы просили эффективный код, вы могли бы создать Наборисключает и проверяет точное совпадение первой части тикера (перед /):

  const excludeSet = new Set(exclude);

  tickers = tickers.filter(ticker => !excludeSet.has(ticker.substr(0, ticker.indexOf("/"))));

(работает ли зависит от того, какие именно правила у вас есть)

1 голос
/ 19 мая 2019

Если «приходит как объект из API» означает, что вы на самом деле получаете

{'BTC/USDT': …, 'ETH/BTC': …, 'CELR/BTC': …, …}

а не то, что вы показали в вопросе

['BTC/USDT', 'ETH/BTC', 'CELR/BTC', …]

тогда delete и Object.keys в порядке, хотя вы:

  • не следует использовать map для побочных эффектов (и особенно не только для побочных эффектов) - forEach также совместим

  • не следует использовать циклы for…in для перебора массивов, таких как exclude

Поскольку вы используете let / const, есть большая вероятность, что доступны for…of и Object.entries:

for (const [key, value] of Object.entries(tickers)) {
    for (const base of exclude) {
        if (key.includes(base)) {
            delete tickers[key]
            break
        }
    }
}

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

0 голосов
/ 19 мая 2019
let   tickers = ['BTC/USDT','ETH/BTC','CELR/BTC',....];
const exclude = ['MATIC', 'CELR'];

Для сокращения функции вы можете использовать every () и indexOf () методы

tickers = tickers.filter((ticker, i) => exclude.every((v) =>  ticker.indexOf(v) == -1));

let   tickers = ['BTC/USDT','ETH/BTC','CELR/BTC'];
const exclude = ['MATIC', 'CELR'];

tickers = tickers.filter((ticker, i) => exclude.every((v) =>  ticker.indexOf(v) == -1));

console.log(tickers)

Каждый метод выполняет предоставленную функцию обратного вызова один раз для каждого элемента в массиве, пока не найдет тот, где обратный вызов возвращает ложное значение (значение, котороестановится ложным при преобразовании в логическое значение).Если такой элемент найден, метод each немедленно возвращает false.В противном случае, если обратный вызов вернул истинное значение для всех элементов, каждый вернет истинное значение.обратный вызов вызывается только для индексов массива, которым присвоены значения;он не вызывается для индексов, которые были удалены или которым никогда не присваивались значения. ( Отсюда )

0 голосов
/ 19 мая 2019

Вы просили эффективный, поэтому вы должны смотреть на Установить , который обеспечивает O(1) время поиска.

Следующая программа исключит любой тикер, в котором любая валюта соответствует исключенному значению. Например, исключая CELR удалит CELR/BTC и FOO/CELR ниже -

const filterTickers = (excludes = [], tickers = []) => {
  const s = new Set(excludes)
  return tickers.filter(t => t.split('/').every(x => !s.has(x)))
}

const result =
  filterTickers(['MATIC', 'CELR'], ['BTC/USDT','ETH/BTC','CELR/BTC','FOO/CELR'])

console.log(result)
// [ "BTC/USDT", "ETH/BTC" ]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...