Разделить массив на небольшие массивы на основе текста в значениях

У меня есть большой массив, который выглядит как этот пример:

let array = ['aa-we', 'aa-we__qq', 'aa-we__qw', 'gsPlsOdd', 'bc-po-lp', 'bc-po-lp--ps', 'de', 'de__io', 'de__sl', 'de--xz', 'ccsDdd'];

я хочу разделить этот массив на небольшие массивы по значениям:

let array = [
  ['aa-we', 'aa-we__qq', 'aa-we__qw'],
  ['bc-po-lp', 'bc-po-lp--ps'],
  ['de', 'de__io', 'de__sl', 'de--xz']  
]

// and camelcase strings should be removed 

Значения в массиве имеют синтаксис, подобный селекторам БЭМ, поэтому, если префикс разных строк одинаков, они должны быть заключены в один массив.

Как мне это сделать, если возможно, без дополнительных библиотек?

Спасибо за помощь или советы!

может это тоже объект?

yunzen 12.02.2019 10:45

Привет! Пожалуйста, возьмите тур (вы получите значок!) и прочитайте центр помощи, в частности Как задать хороший вопрос?. Лучше всего провести исследование, поиск для связанных тем на SO, и попробовать. Если вы застряли и не можете выбраться после дополнительных исследований и поиска, опубликуйте минимальный воспроизводимый пример свою попытку и конкретно укажите, где вы застряли. Люди будут рады помочь.

T.J. Crowder 12.02.2019 10:46

@yunzen нет, только массив.

Vladimir Humeniuk 12.02.2019 10:46

Почему в выводе нет gsPlsOdd, а есть de?

Mark 12.02.2019 10:50

@MarkMeyer Я думаю, потому что gsPlsOdd - верблюжий. OP написал в комментарии к коду «и строки в верблюжьем регистре должны быть удалены»

Seblor 12.02.2019 10:51

@MarkMeyer, потому что мне не нужны строки, написанные в camelCase.

Vladimir Humeniuk 12.02.2019 10:51

Считаются ли элементы строчными()?

yunzen 12.02.2019 11:12
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
7
78
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Алгоритм может быть следующим:

  1. Создать Map<Prefix,ValuesArray>
  2. Для каждого элемента массива:
    • Получите его префикс, например. "ab", пропустить элемент, если он недействителен (например, не существует префикса или верблюжьего регистра)
    • Добавить в соответствующее хешированное ведро
  3. Объединить значения из Map в один массив

В JS есть все примитивы для реализации этого, просто взгляните на Map/Object для хеширования и Array (map/filter/reduce) для обработки.

Я бы сделал что-то подобное, а затем отфильтровал бы то, что вам не нужно.

let array = ['aa-we', 'aa-we__qq', 'aa-we__qw', 'gsPlsOdd', 'bc-po-lp', 'bc-po-lp--ps', 'de', 'de__io', 'de__sl', 'de--xz', 'ccsDdd'];

array = array.filter((a) => !a.match(/[A-Z]/))

let result = groupBy(array, (str)=> str.split(/[-_]/)[0])

console.info(Object.values(result))

function groupBy(arr, condition) {
  return arr.reduce((result, current) => {
    const key = condition(current);
    (result[key] || (result[key] = [])).push(current)
    return result
  }, {})
}

Смотрите комментарии под вопросом. Нет верблюжьего корпуса, как у gsPlsOdd.

Mark 12.02.2019 11:03

Отсюда и «а затем отфильтровать то, что вам не нужно».

James Coyle 12.02.2019 11:04

Не видел этого. Не лучше ли фильтровать по списку, чтобы не смотреть на все дважды.

Mark 12.02.2019 11:05

Обновлено, чтобы сделать это.

James Coyle 12.02.2019 11:09

Вы даже можете изменить функцию, переданную groupBy, чтобы сгруппировать что-либо недопустимое в один ключ, а затем delete этот ключ или изменить функцию groupBy, чтобы она была более специализированной для этой задачи. Я просто взял его из своих вспомогательных методов.

James Coyle 12.02.2019 11:15
Ответ принят как подходящий

console.clear()
let data = [
  "aa-we",
  "aa-we__qq",
  "aa-we__qw",
  "gsPlsOdd",
  "bc-po-lp",
  "bc-po-lp--ps",
  "de",
  "de__io",
  "de__sl",
  "de--xz",
  "ccsDdd",
];


resultO = data.reduce((acc, val, idx) => {
  if (val.match(/[A-Z]/)) {return acc;}
  const sel = val.replace(/^(.*)(__|--).*$/g, "$1");
  acc[sel] = acc[sel] || [];
  acc[sel].push(val)
  return acc;
}, {})
resultA = Object.values(resultO)

console.info(resultA)

Мне также нравится отвечать Джеймса Койла. Он имеет более общий подход

yunzen 12.02.2019 11:33

Другие вопросы по теме