如何正确过滤数组(同时保留原始数据)
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)}
/>
我有一点问题,我不知道如何正确解决。
我有一个数组用来填充我的 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)}
/>