如何正确过滤数组(同时保留原始数据)

How to properly filter array (while retaining original data aswell)

我有一点问题,我不知道如何正确解决。

我有一个数组用来填充我的 DataTable,当值被添加到数组时,它也会反映在 table 中。添加和删​​除效果很好。我怎么想在用户输入一些数据到搜索字段时搜索数组,如果用户输入数据并按“搜索”它会起作用,但是我希望搜索响应输入更改,所以每次用户按下某个字母时它就会开始过滤器。

 let people = [
{ name: 'Jack', lastName: 'London', age: 25, id: 1 },
{ name: 'John', lastName: 'Doe', age: 33, id: 2 },
{ name: 'Jamie', lastName: 'Mith', age: 22, id: 3 },
  ];



 function sortArray(string) {
    var arr = [];
    for (var i = 0; i < people.length; i++) {
      if (people[i].string == string) arr.push(people[i]);
    }
    return (people = [...arr]);
  }

现在事情有点复杂,假设用户在搜索框中输入字母 S,函数过滤数组,(现在数组中没有任何内容),所以我需要在某处保存 origina 数组的值作为参考

我确实尝试过过滤它,

function filter(arr, string) {
var regex = new RegExp('.*' + string + '.*');
return arr.filter(function (el) {
  return regex.exec(el.name);
});

}

但也没有运气。

我正在使用 Svelte,IBM Carbon 数据table,(尽管我认为这不会改变任何东西)。

我什至可能以某种方式让它工作,但我认为它非常低效,所以如果有人有解决方案,我将非常感激。

此外,当我们使用扩展运算符复制数组且数据量适中时,成本(性能方面)是多少?

Filtering/performance:

在过滤方面,array.filter 从未让我在性能方面感到失望,我曾遇到过在您甚至没有注意到的情况下过滤多达 10.000 个项目的情况。 您也无法通过使用上次搜索的子集来改进搜索。 用户可以一起退格或删除过滤器,所以对原始子集进行过滤基本上是必须的。

在性能方面最大的问题是可视化。 如果您有一个 table 可以同时可视化所有记录,那么它们都必须被渲染,这是非常昂贵的。 因此,例如支持分页的组件可以提高您的性能。 因此,array.filter 不会成为您的瓶颈。

逻辑(旁注):

您的过滤器至少有 1 个问题。 你使用 .* => 这意味着你将永远无法过滤名字的第一个或最后一个字母,.?解决这个问题。

样本:

我添加了最边缘的样本(基于您的数据)以对数据进行快速过滤。仅供参考。都是内联的,没有花哨的东西。


<html>
  <body>
    <input type="text" id="input" />
    <ul id="output">
    </ul>
  </body>
  <script>
   let people = [
    { name: 'Jack', lastName: 'London', age: 25, id: 1 },
    { name: 'John', lastName: 'Doe', age: 33, id: 2 },
    { name: 'Jamie', lastName: 'Mith', age: 22, id: 3 }
   ];
   
   function filter(arr, string) {
     var regex = new RegExp('.?' + string + '.?');
     return arr.filter(function (el) {
       return regex.exec(el.name);
     });
   };
   
   const inp = document.getElementById("input");
   const outp = document.getElementById("output");
   
   inp.addEventListener("keyup", event => {
     render();
   });
   
   function render(){
     var result = filter(people, inp.value);
     outp.innerHTML = '';
     for (var i = 0; i < result.length; i++){
       var node = document.createElement("li");
       node.appendChild(document.createTextNode(result[i].name));
       outp.appendChild(node);
     }
     console.log(result);
   };
  </script>
</html>

您可能想要显示搜索结果数据,而不是 displaying/modifying 您的数据。您仍然可以像现在一样 add/edit/delete 原始数据,但只显示数据 table 中与搜索查询匹配的项目,或者如果搜索查询为空则显示所有项目。

在使用 IBM Carbon DataTable 时,您可以使用 returns 对象数组作为行值的任何函数,一个简单的示例可能如下所示:

<script>
 import { DataTable } from "carbon-components-svelte";
 let  value = "";
 let people = [
    { name: 'Jack', lastName: 'London', age: 25, id: 1 },
    { name: 'John', lastName: 'Doe', age: 33, id: 2 },
    { name: 'Jamie', lastName: 'Mith', age: 22, id: 3 }
 ];

 function search(items, query) {
    if (!query) {
        return items
    }
    const results = items.filter(item => {
        // Replace with whatever filter method you like
        return item.name.toLowerCase().includes(query.toLowerCase()) || item.lastName.toLowerCase().includes(query.toLowerCase())
    })
    return results
}
</script>

<label for="search">
  <input id="search" bind:value />
</label>
<!-- The rows value calls a function that returns an array after filtering it, this will be called on every change to the query -->
<DataTable
  headers={[{ key: 'name', value: 'First name' }, { key: 'lastName', value: 'Last name' }, { key: 'age', value: 'Age' }, { key: 'id', value: 'Id' }]}
  rows={search(people, value)}
/>