Как искать несколько строк с помощью AND, используя JS-фильтр в реакции?

Мой вопрос заключается в следующем. Я пытаюсь создать реагирующий элемент с помощью R, и я в основном хочу, чтобы панель поиска могла выполнять глобальный поиск нескольких строк, разделенных пробелом; так, например, я хочу иметь возможность вставлять в строку поиска следующее: «FOO BAR» и иметь возможность получать все строки, содержащие (в каждом порядке и в каждом столбце) как FOO, так и BAR; термины не обязательно должны находиться в одном столбце, но должны быть в одной строке.

Я изо всех сил пытаюсь это сделать; Я следую нескольким примерам в Интернете и нашел это в Интернете: https://github.com/glin/reactable/issues/222, в котором пользователь предлагает метод (см. код ниже из этого вопроса на github), который действительно работает хорошо. объединение разных строк с помощью OR.

library(reactable)
data <- as.data.frame(datasets::Titanic)
myFilterMethod <- JS('function(rows, columnIds, filterValue) {
  /*
    pattern defines a RegEx text based on the users input. 
    In this users input,  all occurences of spacebar are replaced by an OR sign. 
    This is done so that if at least one his keywords is true, the row is displayed
    However, if the expression ends with an OR sign, the OR sign should be removed. 
    If this is not done,  then expressions ending in a spacebar will end in an OR sign 
    and will always give true. This is what the second replace does.
  */
      
  const pattern = new RegExp(filterValue.replace(/ /g, "|").replace(/\\|$/, ""))
  return rows.filter(function(row) {
    return columnIds.some(function(columnId) {
      return pattern.test(row.values[columnId]) 
      // Use the pattern defined above to test the rows 
      // and return those that pass the patternn
    })
  })
}')

reactable(
  data, searchable = TRUE, 
  searchMethod = myFilterMethod)

Как я могу создать аналогичную вещь, но объединить строку с помощью AND вместо OR?

Поведение ключевого слова "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) для оценки ваших знаний,...
4
0
83
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Следующая идея должна сработать:

  1. Разделите поисковый запрос по пробелам () на токены.
  2. Начните с полного набора строк и отфильтруйте его до тех строк, которые содержат первый токен.
  3. К этому отфильтрованному набору строк применяется фильтр со следующим токеном, пока не будут обработаны все токены.

Функция Javascript reduce здесь ваш друг:

library(reactable)
data <- as.data.frame(datasets::Titanic)

searchForMultipleStrings  <- JS("
function(rows, columnIds, filterValue) {
  // tokens is an array of all search words
  const tokens = filterValue.split(' ');
  const result = tokens.reduce(
    function (filtered_rows, token) {
      return filtered_rows.filter(function (row) {
        // need to transform object to array
        const vals = Object.keys(row.values).map((key) => row.values[key]);
        // for each entry in the row look if there is at least one single match 
        return vals.some((value) => value == token)
      });
    },
    rows
  )
  return result;
}
")

reactable(
  data, searchable = TRUE, 
  searchMethod = searchForMultipleStrings)

Н.Б. Я искал точные совпадения здесь (==). Если вам нужна гибкость в использовании какого-то частичного соответствия, вы можете включить regex в функцию .some().


Обновлять

Чтобы обеспечить «живой» поиск без учета регистра, адаптируйте код следующим образом:

searchForMultipleStrings  <- JS("
function(rows, columnIds, filterValue) {
  // tokens is an array of all search words
  const tokens = filterValue.split(' ');
  const result = tokens.reduce(
    function (filtered_rows, token) {
      return filtered_rows.filter(function (row) {
        // need to transform object to array
        const vals = Object.keys(row.values).map((key) => row.values[key]);
        // for each entry in the row look if there is at least one single match 
        const re = new RegExp('^' + token + '\\S*', 'i');
        return vals.some((value) => re.test(value))
      });
    },
    rows
  )
  return result;
}
")

Это позволяет обеспечить частичное совпадение с начала строки. То есть строка поиска ma ch y 3 будет соответствовать Male | Child | Yes | 3rd. Он нечувствителен к регистру. В зависимости от ваших конечных потребностей вам может потребоваться дополнительная адаптация регулярного выражения.

Спасибо! Ваше решение тоже работает. По сравнению с другим один отличается тем, что одному нужно ввести строку, которая точно соответствует строке, указанной в таблице, в то время как другой имеет преимущество своего рода «живого поиска». Что предпочтительнее, зависит от индивидуальных потребностей. Спасибо за вашу помощь.

userq8957289475 01.07.2024 15:31

Обновил мой ответ запрошенной функцией.

thothal 01.07.2024 15:42
Ответ принят как подходящий

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

library(reactable)

myFilterMethod <- JS('
function(rows, columnIds, filterValue) {
    let arrFilterValues = filterValue.split(" ");

    return rows.filter(function(row) {
        return arrFilterValues.map(function(e) {
            return columnIds.some(function(columnId) {
                return new RegExp(e).test(row.values[columnId])
            });
        }).every(v => v === true);
    });
}')

reactable(
  as.data.frame(datasets::Titanic), searchable=TRUE, 
  searchMethod=myFilterMethod)

Огромное спасибо, это сработало - по сравнению со "стандартной" реагирующей формой поиска она кажется чувствительной к регистру - как можно сделать ее нечувствительной к регистру (т. е. в примере "мужчина" должен получать те же результаты, что и "мужчина" ")? Я полагаю, что можно применить filterValue.toLowerCase(filterValue.split(" ")) к предыдущему коду, но, похоже, это не работает.

userq8957289475 01.07.2024 15:35

Будьте осторожны с нечувствительностью к регистру в этом подходе. male будет соответствовать как Female, так и Male, в зависимости от того, чего вы хотите, его может быть нежелательным.

thothal 01.07.2024 15:50

@thothal, это тоже может быть желательно, и мне любопытно, как сделать этот пример нечувствительным к регистру, поскольку я также пытаюсь немного выучить язык JS. Есть идеи?

userq8957289475 01.07.2024 15:51

@thothal Я так не думаю. Если я буду искать male, то получу только записи Female, используя приведенный выше код ...

Jan 01.07.2024 16:15

@Jan - видимо, я сам узнал - просто используйте return new RegExp(e,"i").test(row.values[columnId]) в вашем примере, чтобы сделать код нечувствительным к регистру. Спасибо! Подумайте о том, чтобы включить это в свой ответ, чтобы люди могли получить полную картину, если это необходимо.

userq8957289475 01.07.2024 16:20

@jan, в твоей текущей реализации это правда. Однако как только вы добавите нечувствительность к регистру, вы попадете в эту ловушку.

thothal 01.07.2024 17:10

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

Похожие вопросы

Расшифровка JavaScript Web Crypto API (RSA-OAEP) в Java
Можно ли добавить прослушиватель событий в пользовательскую строку заголовка, используемую для перетаскивания окна в безрамочном окне?
Реакция: «.map не является функцией»
Обновление документа Firestore несколько раз с помощью функции триггера события перезаписывает или прекращает обновление после нескольких триггеров
Не отмечено runtime.lastError: порт сообщения закрыт до получения ответа. Расширение Chrome
Window.opener и window.parent не работают во всплывающем дочернем окне
Получите значение null в контроллере при реализации IEnumerable в модели ASP NET
Как программно проверить, отключен ли на веб-сайте щелчок правой кнопкой мыши?
Vue 3 API композиции, не может вернуть значение из вспомогательной функции в компонент
422 Ошибка необрабатываемого объекта при отправке данных формы на серверную часть FastAPI с использованием ReactJs и Fetch API во внешнем интерфейсе