- Home »

Метод filter массива в JavaScript — как использовать
Массивы в JavaScript — это хлеб и масло для любого разработчика, а метод filter()
без преувеличения можно назвать одним из самых мощных инструментов для работы с данными. Если вы настраиваете серверы, пишете скрипты для автоматизации или парсите логи, то этот метод станет вашим верным спутником в решении множества задач.
Думаю, многие из вас сталкивались с ситуацией, когда нужно отфильтровать массив процессов в системе, выбрать только нужные строки из конфигурационного файла или обработать JSON-ответ от API. Именно в таких случаях filter()
показывает свою силу — он позволяет создавать новые массивы на основе определённых условий, не мутируя исходные данные.
Сегодня разберём, как правильно использовать этот метод, рассмотрим практические примеры из повседневной работы с серверами и автоматизацией, а также покажем, как интегрировать его в ваши Node.js скрипты для мониторинга и управления инфраструктурой.
Как работает метод filter()
Метод filter()
создаёт новый массив, содержащий только те элементы исходного массива, которые проходят проверку, реализованную в переданной функции. Проще говоря, вы задаёте условие, а метод возвращает только подходящие элементы.
Синтаксис выглядит следующим образом:
array.filter(callback(element, index, array), thisArg)
Где:
callback
— функция, которая проверяет каждый элементelement
— текущий элемент массиваindex
— индекс текущего элемента (необязательный)array
— исходный массив (необязательный)thisArg
— значениеthis
для функции callback (необязательный)
Важно помнить, что filter()
не изменяет исходный массив, а создаёт новый. Это делает его безопасным для использования в функциональном программировании.
Пошаговая настройка и базовые примеры
Давайте начнём с простых примеров, которые помогут понять основы работы с методом:
// Пример 1: Фильтрация чисел
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const evenNumbers = numbers.filter(num => num % 2 === 0);
console.log(evenNumbers); // [2, 4, 6, 8, 10]
// Пример 2: Фильтрация строк
const processes = ['nginx', 'apache2', 'mysql', 'redis', 'postgres'];
const webServers = processes.filter(process => process.includes('nginx') || process.includes('apache'));
console.log(webServers); // ['nginx', 'apache2']
// Пример 3: Фильтрация объектов
const servers = [
{ name: 'web-01', cpu: 85, memory: 70, status: 'active' },
{ name: 'web-02', cpu: 45, memory: 60, status: 'active' },
{ name: 'db-01', cpu: 90, memory: 85, status: 'warning' },
{ name: 'cache-01', cpu: 25, memory: 40, status: 'active' }
];
const overloadedServers = servers.filter(server => server.cpu > 80 || server.memory > 80);
console.log(overloadedServers);
// [{ name: 'web-01', cpu: 85, memory: 70, status: 'active' },
// { name: 'db-01', cpu: 90, memory: 85, status: 'warning' }]
Практические примеры для системного администрирования
Теперь рассмотрим реальные сценарии, с которыми сталкивается каждый, кто работает с серверами:
Анализ логов веб-сервера
const fs = require('fs');
const path = require('path');
// Парсим access.log и фильтруем ошибки
function parseAccessLog(logPath) {
const logData = fs.readFileSync(logPath, 'utf8').split('\n');
const errorEntries = logData
.filter(line => line.includes(' 4') || line.includes(' 5')) // HTTP 4xx, 5xx
.filter(line => line.trim() !== '') // Удаляем пустые строки
.map(line => {
const parts = line.split(' ');
return {
ip: parts[0],
timestamp: parts[3] + ' ' + parts[4],
method: parts[5],
url: parts[6],
status: parts[8],
size: parts[9]
};
});
return errorEntries;
}
// Использование
const errors = parseAccessLog('/var/log/nginx/access.log');
console.log(`Найдено ${errors.length} ошибок`);
Мониторинг процессов системы
const { exec } = require('child_process');
function getHighCPUProcesses(threshold = 80) {
return new Promise((resolve, reject) => {
exec('ps aux --sort=-%cpu', (error, stdout) => {
if (error) {
reject(error);
return;
}
const processes = stdout.split('\n')
.slice(1) // Убираем заголовок
.filter(line => line.trim() !== '')
.map(line => {
const parts = line.trim().split(/\s+/);
return {
user: parts[0],
pid: parts[1],
cpu: parseFloat(parts[2]),
memory: parseFloat(parts[3]),
command: parts.slice(10).join(' ')
};
})
.filter(process => process.cpu > threshold);
resolve(processes);
});
});
}
// Использование
getHighCPUProcesses(50).then(processes => {
console.log('Процессы с высокой нагрузкой на CPU:');
processes.forEach(p => {
console.log(`${p.command} (PID: ${p.pid}, CPU: ${p.cpu}%)`);
});
});
Фильтрация конфигураций Docker контейнеров
const { exec } = require('child_process');
function getRunningContainers() {
return new Promise((resolve, reject) => {
exec('docker ps --format "{{.Names}},{{.Status}},{{.Ports}}"', (error, stdout) => {
if (error) {
reject(error);
return;
}
const containers = stdout.trim().split('\n')
.filter(line => line.trim() !== '')
.map(line => {
const [name, status, ports] = line.split(',');
return { name, status, ports };
})
.filter(container => container.status.includes('Up')); // Только запущенные
resolve(containers);
});
});
}
// Фильтрация по портам
function getWebContainers(containers) {
return containers.filter(container =>
container.ports.includes(':80->') ||
container.ports.includes(':443->') ||
container.ports.includes(':8080->')
);
}
Продвинутые техники и комбинации
Настоящая мощь filter()
раскрывается при его комбинации с другими методами массивов:
// Цепочка методов для обработки серверной статистики
const serverMetrics = [
{ server: 'web-01', timestamp: '2024-01-15T10:00:00Z', cpu: 85, memory: 70 },
{ server: 'web-01', timestamp: '2024-01-15T10:05:00Z', cpu: 90, memory: 75 },
{ server: 'web-02', timestamp: '2024-01-15T10:00:00Z', cpu: 45, memory: 60 },
{ server: 'web-02', timestamp: '2024-01-15T10:05:00Z', cpu: 50, memory: 65 },
{ server: 'db-01', timestamp: '2024-01-15T10:00:00Z', cpu: 95, memory: 85 }
];
// Находим критичные метрики и группируем по серверам
const criticalMetrics = serverMetrics
.filter(metric => metric.cpu > 80 || metric.memory > 80)
.map(metric => ({
...metric,
severity: metric.cpu > 90 || metric.memory > 90 ? 'critical' : 'warning'
}))
.reduce((acc, metric) => {
if (!acc[metric.server]) {
acc[metric.server] = [];
}
acc[metric.server].push(metric);
return acc;
}, {});
console.log(criticalMetrics);
Сравнение с альтернативными подходами
Метод | Производительность | Читаемость | Гибкость | Подходит для |
---|---|---|---|---|
filter() | Высокая | Отличная | Высокая | Большинство задач |
for loop | Очень высокая | Средняя | Максимальная | Критичные по производительности операции |
forEach + push | Средняя | Низкая | Средняя | Не рекомендуется |
reduce() | Средняя | Низкая | Очень высокая | Сложные трансформации |
Интеграция с популярными библиотеками
Метод filter()
отлично работает с библиотеками, которые часто используются в серверных приложениях:
Lodash
const _ = require('lodash');
// Комбинация filter с lodash утилитами
const servers = [
{ name: 'web-01', tags: ['production', 'frontend'], cpu: 85 },
{ name: 'web-02', tags: ['staging', 'frontend'], cpu: 45 },
{ name: 'db-01', tags: ['production', 'database'], cpu: 90 }
];
// Используем lodash для более сложных фильтров
const productionServers = servers.filter(server =>
_.includes(server.tags, 'production') && server.cpu < 95
);
// Или используем встроенные методы lodash
const filteredServers = _.filter(servers, server =>
_.some(server.tags, tag => tag.includes('prod'))
);
Moment.js для фильтрации по времени
const moment = require('moment');
const logs = [
{ message: 'Server started', timestamp: '2024-01-15T08:00:00Z' },
{ message: 'High CPU usage', timestamp: '2024-01-15T10:30:00Z' },
{ message: 'Database connection lost', timestamp: '2024-01-15T14:45:00Z' }
];
// Фильтруем логи за последние 6 часов
const recentLogs = logs.filter(log =>
moment(log.timestamp).isAfter(moment().subtract(6, 'hours'))
);
Оптимизация и производительность
При работе с большими объёмами данных важно учитывать производительность:
// Неэффективно - множественные проходы
const data = getLargeDataSet();
const step1 = data.filter(item => item.type === 'server');
const step2 = step1.filter(item => item.status === 'active');
const step3 = step2.filter(item => item.cpu > 80);
// Эффективно - один проход
const optimized = data.filter(item =>
item.type === 'server' &&
item.status === 'active' &&
item.cpu > 80
);
// Для очень больших массивов можно использовать индексы
const indexedData = new Map();
data.forEach((item, index) => {
if (item.type === 'server') {
indexedData.set(item.id, { ...item, originalIndex: index });
}
});
Автоматизация и скрипты мониторинга
Создадим полноценный скрипт мониторинга, который можно запускать по cron:
#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
const { exec } = require('child_process');
class ServerMonitor {
constructor(config) {
this.config = config;
this.alerts = [];
}
async checkDiskSpace() {
return new Promise((resolve, reject) => {
exec("df -h | grep -E '^/dev/'", (error, stdout) => {
if (error) {
reject(error);
return;
}
const disks = stdout.trim().split('\n')
.map(line => {
const parts = line.split(/\s+/);
return {
filesystem: parts[0],
size: parts[1],
used: parts[2],
available: parts[3],
usePercent: parseInt(parts[4].replace('%', '')),
mountPoint: parts[5]
};
})
.filter(disk => disk.usePercent > this.config.diskThreshold);
resolve(disks);
});
});
}
async checkMemory() {
return new Promise((resolve, reject) => {
exec('free -m', (error, stdout) => {
if (error) {
reject(error);
return;
}
const lines = stdout.trim().split('\n');
const memoryLine = lines[1].split(/\s+/);
const total = parseInt(memoryLine[1]);
const available = parseInt(memoryLine[6]);
const usedPercent = Math.round(((total - available) / total) * 100);
resolve({
total,
available,
usedPercent,
alert: usedPercent > this.config.memoryThreshold
});
});
});
}
async runMonitoring() {
console.log('🔍 Запуск мониторинга сервера...');
try {
const [diskAlerts, memoryStatus] = await Promise.all([
this.checkDiskSpace(),
this.checkMemory()
]);
// Фильтруем критичные диски
const criticalDisks = diskAlerts.filter(disk => disk.usePercent > 90);
if (criticalDisks.length > 0) {
console.log('🚨 Критичное заполнение дисков:');
criticalDisks.forEach(disk => {
console.log(` ${disk.mountPoint}: ${disk.usePercent}%`);
});
}
if (memoryStatus.alert) {
console.log(`🚨 Высокое использование памяти: ${memoryStatus.usedPercent}%`);
}
// Сохраняем результаты
const results = {
timestamp: new Date().toISOString(),
diskAlerts,
memoryStatus,
criticalDisks
};
fs.writeFileSync('/tmp/server-monitor.json', JSON.stringify(results, null, 2));
console.log('✅ Мониторинг завершён');
} catch (error) {
console.error('❌ Ошибка мониторинга:', error);
}
}
}
// Конфигурация
const config = {
diskThreshold: 80,
memoryThreshold: 85
};
// Запуск
const monitor = new ServerMonitor(config);
monitor.runMonitoring();
Интересные факты и нестандартные применения
Несколько интересных особенностей filter()
, которые могут пригодиться:
- Sparse arrays:
filter()
пропускает пустые элементы массива (holes), что делает его полезным для очистки разреженных массивов - Type coercion: Возвращаемое значение callback приводится к boolean, поэтому можно использовать краткие формы
- Immutability: Идеально подходит для Redux и других state management решений
// Очистка разреженного массива
const sparse = [1, , 3, , 5];
const dense = sparse.filter(() => true); // [1, 3, 5]
// Фильтрация "truthy" значений
const mixed = [0, 1, false, 2, '', 3, null, 4, undefined, 5];
const truthy = mixed.filter(Boolean); // [1, 2, 3, 4, 5]
// Удаление дубликатов (в комбинации с indexOf)
const duplicates = [1, 2, 2, 3, 3, 3, 4];
const unique = duplicates.filter((item, index) => duplicates.indexOf(item) === index);
Развёртывание и тестирование
Для полноценной работы с серверными скриптами рекомендую использовать качественный VPS хостинг с достаточными ресурсами для Node.js приложений. Если планируете обрабатывать большие объёмы данных, стоит рассмотреть выделенный сервер для максимальной производительности.
Заключение и рекомендации
Метод filter()
— это фундаментальный инструмент, который должен быть в арсенале каждого разработчика, работающего с серверными технологиями. Он отлично подходит для:
- Анализа логов и мониторинга системы
- Обработки конфигурационных файлов
- Фильтрации данных в API
- Создания скриптов автоматизации
- Работы с метриками и статистикой
Ключевые принципы использования:
- Всегда возвращайте boolean из callback функции
- Помните, что
filter()
создаёт новый массив - Используйте цепочки методов для сложных операций
- Оптимизируйте условия для больших массивов
- Комбинируйте с другими методами массивов для максимальной эффективности
Освоив filter()
и его интеграцию с серверными задачами, вы сможете создавать более элегантные и производительные решения для автоматизации и мониторинга инфраструктуры.
В этой статье собрана информация и материалы из различных интернет-источников. Мы признаем и ценим работу всех оригинальных авторов, издателей и веб-сайтов. Несмотря на то, что были приложены все усилия для надлежащего указания исходного материала, любая непреднамеренная оплошность или упущение не являются нарушением авторских прав. Все упомянутые товарные знаки, логотипы и изображения являются собственностью соответствующих владельцев. Если вы считаете, что какой-либо контент, использованный в этой статье, нарушает ваши авторские права, немедленно свяжитесь с нами для рассмотрения и принятия оперативных мер.
Данная статья предназначена исключительно для ознакомительных и образовательных целей и не ущемляет права правообладателей. Если какой-либо материал, защищенный авторским правом, был использован без должного упоминания или с нарушением законов об авторском праве, это непреднамеренно, и мы исправим это незамедлительно после уведомления. Обратите внимание, что переиздание, распространение или воспроизведение части или всего содержимого в любой форме запрещено без письменного разрешения автора и владельца веб-сайта. Для получения разрешений или дополнительных запросов, пожалуйста, свяжитесь с нами.