Использование приложения 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);
Обновлен код
Поскольку вы предоставляете классы в виде одной строки, разделенной пробелом, вам сначала необходимо их разделить. Этот код проверяет все классы.
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 результат должен быть истинным, но в вашем случае он выдается как ложный. Небольшое изменение в вашем коде может дать ответ. Спасибо
Хорошо, я не был уверен, в каких именно случаях вы ожидаете здесь истинного/ложного значения.
Есть два формата данных...
Поскольку приходится использовать подходы сравнения, соответствующие различным форматам, массив строковых значений имен по сравнению со строкой значений имен, разделенных пробелами, можно придумать в основном два подхода...
разделить строку имен классов и перебрать полученный массив, чтобы посмотреть, включает ли массив списка классов каждые разделенных имен классов, что делает сложность подходов квадратичной (includes
вложенной внутрь every
) ...
function hasEveryClassName(list, search) {
return search
.trim()
.split(/\s+/)
.every(value => list.includes(value));
}
создайте RegExp из split
и сортируемой строки имен классов, которая затем проверяется против sort
ed и объединенной строковой версии предоставленного массива имен классов. Сложность связана с самим подходом, который требует сортировки обоих участников и создания действительного/работающего регулярного выражения, например. /\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; }
Селигер: Есть ли какой-нибудь более простой способ добиться решения?
@SuryaRPraveen ... вы можете еще раз проверить приведенный выше актуальный ответ.
@Seliger - Спасибо, что исправили мой ответ, правда всегда была ложной, даже если класс присутствует. Я удалил свой ответ и принял ваше решение. Еще раз спасибо....
Пожалуйста, не размещайте код в виде изображений, ссылка: Meta.stackoverflow.com/questions/285551/… Изображения хороши для наглядности, но не для реального кода.