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

Использование приложения Angular, которое вставляет «ng-star-inserted» в каждый элемент узла. Мне нужно проверить, существует ли класс целевого элемента внутри массива.

var footerElementClassList = [
      'footer-links__link',
      'social__link-icon',
      'bottom__link',
    ];

const filtered = footerElementClassList.includes('bottom__link ng-star-inserted');
console.info(filtered); 

Пробовал варианты ниже, но безуспешно

Опция 1

var footerElementClassList = [
      'footer-links__link',
      'social__link-icon',
      'bottom__link',
    ];
var mySet = new Set(footerElementClassList);
var hasB = mySet.has('footer-links__link ng-star-inserted');
console.info(hasB); //false

Вариант 2

var footerElementClassList = [
      'footer-links__link',
      'social__link-icon',
      'bottom__link',
    ];

function hasMatch(value) {
return value = 'bottom__link ng-star-inserted';
}
const filtered = footerElementClassList.filter(hasMatch);
console.info(filtered); //false

Вариант 3

var footerElementClassList = [
      'footer-links__link',
      'social__link-icon',
      'bottom__link',
    ];
console.info(footerElementClassList?.contains('footer-links__link ng-star-inserted'));

Вариант 4

var footerElementClassList = [
      'footer-links__link',
      'social__link-icon',
      'bottom__link',
    ];
const filtered = footerElementClassList.includes('bottom__link ng-star-inserted');
console.info(filtered); 

Пожалуйста, не размещайте код в виде изображений, ссылка: Meta.stackoverflow.com/questions/285551/… Изображения хороши для наглядности, но не для реального кода.

Mark Schultheiss 29.07.2024 15:02

Обновлен код

Surya R Praveen 29.07.2024 16:20
Поведение ключевого слова "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
2
75
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Поскольку вы предоставляете классы в виде одной строки, разделенной пробелом, вам сначала необходимо их разделить. Этот код проверяет все классы.

var footerElementClassList = [
      'footer-links__link',
      'social__link-icon',
      'bottom__link',
    ];

function containesAll(classString, classList){
  const classes = classString.split(' ');
 
  for(cls of classes)
  {
    if (!classList.includes(cls))
    {
      return false;
    }
  }
  return true;
}

console.info(`containesAll('bottom__link ng-star-inserted', footerElementClassList): ${containesAll('bottom__link ng-star-inserted', footerElementClassList)}`) // false
console.info(`containesAll('bottom__link social__link-icon', footerElementClassList): ${containesAll('bottom__link social__link-icon', footerElementClassList)}`) // true

При поиске класса Bottom__link ng-star-inserted результат должен быть истинным, но в вашем случае он выдается как ложный. Небольшое изменение в вашем коде может дать ответ. Спасибо

Surya R Praveen 30.07.2024 13:32

Хорошо, я не был уверен, в каких именно случаях вы ожидаете здесь истинного/ложного значения.

arch 30.07.2024 18:51
Ответ принят как подходящий

Есть два формата данных...

  • список имен классов на основе массива
  • поисковый запрос представлен в виде строки имен классов, разделенных пробелами.

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

  • разделить строку имен классов и перебрать полученный массив, чтобы посмотреть, включает ли массив списка классов каждые разделенных имен классов, что делает сложность подходов квадратичной (includes вложенной внутрь every ) ...

    function hasEveryClassName(list, search) {
      return search
        .trim()
        .split(/\s+/)
        .every(value => list.includes(value));
    }
    
  • создайте RegExp из split и сортируемой строки имен классов, которая затем проверяется против sorted и объединенной строковой версии предоставленного массива имен классов. Сложность связана с самим подходом, который требует сортировки обоих участников и создания действительного/работающего регулярного выражения, например. /\bbottom__link\b.*?\bng-star-inserted\b/ на лету...

    function hasEveryClassName(list, search) {
      return RegExp([
        '\\b',
        search
          .trim()
          .split(/\s+/)
          .sort()
          .join('\\b.*?\\b'),
        '\\b',
      ].join('')).test(list.sort().join(' '));
    }
    

... рабочий пример кода...

const classList = [
  'footer-links__link',
  'social__link-icon',
  'bottom__link',
];
const classNames = 'bottom__link ng-star-inserted';


function hasEveryClassName_v1(list, search) {
  return search
    .trim()
    .split(/\s+/)
    .every(value => list.includes(value));
}
console.info('\n... nested `every`/`includes` approach ...\n\n');

console.info(
  `hasEveryClassName_v1(\n  ${ JSON.stringify(classList) },\n  ${ JSON.stringify(classNames) },\n) ...`,
  hasEveryClassName_v1(classList, classNames),
);
classList.push('ng-star-inserted');

console.info(
  `hasEveryClassName_v1(\n  ${ JSON.stringify(classList) },\n  ${ JSON.stringify(classNames) },\n) ...`,
  hasEveryClassName_v1(classList, classNames),
);
classList.pop();


function hasEveryClassName_v2(list, search) {
  return RegExp([
    '\\b',
    search
      .trim()
      .split(/\s+/)
      .sort()
      .join('\\b.*?\\b'),
    '\\b',
  ].join('')).test(list.sort().join(' '));
}
console.info('\n... concatenated sorted name string and regex test based approach ...\n\n');

console.info(
  `hasEveryClassName_v2(\n  ${ JSON.stringify(classList) },\n  ${ JSON.stringify(classNames) },\n) ...`,
  hasEveryClassName_v2(classList, classNames),
);
classList.unshift('ng-star-inserted');

console.info(
  `hasEveryClassName_v2(\n  ${ JSON.stringify(classList) },\n  ${ JSON.stringify(classNames) },\n) ...`,
  hasEveryClassName_v2(classList, classNames),
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

Редактировать... поскольку ОП в своем последнем обновлении представил Установить как возможную структуру для работы, а также для того, чтобы ответить на комментарий ОП к этому ответу...

Есть ли какой-нибудь более простой способ найти решение?

Конечно, хотя первое представленное решение на основе every/includes уже настолько просто, насколько это возможно, замена массива/списка имен классов представлением этого массива на основе Set является более производительным.

Ранее опубликованное решение...

function hasEveryClassName(list, search) {
  return search
    .trim()
    .split(/\s+/)
    .every(value => list.includes(value));
}

... затем меняется на...

function hasEveryClassName(list, search) {
  const lookup = new Set(list);

  return search
    .trim()
    .split(/\s+/)
    .every(value => lookup.has(value))
}

... или, еще лучше...

function hasEveryClassName(lookup, search) {
  return search
    .trim()
    .split(/\s+/)
    .every(value => lookup.has(value));
}

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

Переход от структуры массива к структуре набора снижает временную сложность решения с квадратичной до линейной.

... рабочий пример кода...

const classNameLookup = new Set([
  'footer-links__link',
  'social__link-icon',
  'bottom__link',
]);
const classNames = 'bottom__link ng-star-inserted';

function hasEveryClassName(lookup, search) {
  return search
    .trim()
    .split(/\s+/)
    .every(value => lookup.has(value));
}

console.info(
  `hasEveryClassName(\n  ${ JSON.stringify([...classNameLookup.values()]) },\n  ${ JSON.stringify(classNames) },\n) ...`,
  hasEveryClassName(classNameLookup, classNames),
);
classNameLookup.add('ng-star-inserted');

console.info(
  `hasEveryClassName(\n  ${ JSON.stringify([...classNameLookup.values()]) },\n  ${ JSON.stringify(classNames) },\n) ...`,
  hasEveryClassName(classNameLookup, classNames),
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

Селигер: Есть ли какой-нибудь более простой способ добиться решения?

Surya R Praveen 30.07.2024 10:37

@SuryaRPraveen ... вы можете еще раз проверить приведенный выше актуальный ответ.

Peter Seliger 30.07.2024 11:26

@Seliger - Спасибо, что исправили мой ответ, правда всегда была ложной, даже если класс присутствует. Я удалил свой ответ и принял ваше решение. Еще раз спасибо....

Surya R Praveen 31.07.2024 04:12

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