如何在reactable中使用JS过滤器通过AND搜索多个字符串?

问题描述 投票:0回答:1

我的问题如下。我正在尝试使用 R 创建一个可反应的,并且我基本上希望搜索栏能够全局搜索由空格分隔的multiple字符串;例如,我希望能够在搜索栏中插入以下内容:“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 连接字符串?

javascript r reactable tanstack
1个回答
0
投票

以下想法应该可行:

  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)
© www.soinside.com 2019 - 2024. All rights reserved.