数组 - Javascript - 使用输入搜索过滤对象数组
Posted
技术标签:
【中文标题】数组 - Javascript - 使用输入搜索过滤对象数组【英文标题】:Arrays - Javascript - filter array of objects using input search 【发布时间】:2017-08-17 13:32:15 【问题描述】:我正在尝试使用 react 过滤列表,但令人惊讶的是,对于这样一个常见的任务,在网上找不到任何东西来帮助我实现这一点。
我有一组用户,然后我想过滤它们(从名称开始 - 我可以按年龄进行过滤)。 该数组在我的 redux 存储中,如下所示。
let users = [
name: 'Raul',
age: 29
,
name: 'Mario',
age: 22
];
我的整个组件如下所示。
class Test extends Component
constructor(props)
super(props);
this.state =
users: this.props.users
;
this.filterList = this.filterList.bind(this);
componentWillReceiveProps(nextProps)
this.setState(
users: nextProps.users
);
filterList(event)
let users = this.state.users;
users = users.filter(function(user)
//unsure what to do here
);
this.setState(users: users);
render()
const userList = this.state.users.map((user) =>
return <li>user.name user.age</li>;
);
return(
<input type="text" placeholder="Search" onChange=this.filterList/>
<ul>
userList
</ul>
);
【问题讨论】:
过滤条件是什么? 道歉@pablogq 按名称过滤。理想情况下两者都可以,但可以以名称开头 【参考方案1】:如果您想过滤name
,您可以使用.filter
与.startsWith
或.indexOf
一起为给定用户返回真或假。
您还在 onChange 事件上设置了一个新的用户列表,这迟早会导致一个空数组。这里我使用了仅由道具改变的user
状态,以及在击键发生时改变的filteredUsers
。
class Test extends React.Component
constructor(props)
super(props);
this.state =
users: this.props.users,
filteredUsers: this.props.users,
q: ''
;
this.filterList = this.filterList.bind(this);
this.onChange = this.onChange.bind(this);
componentWillReceiveProps(nextProps)
this.setState(
users: nextProps.users,
filteredUsers: nextProps.users
,
() => this.filterList()
);
onChange(event)
const q = event.target.value.toLowerCase();
this.setState( q , () => this.filterList());
filterList()
let users = this.state.users;
let q = this.state.q;
users = users.filter(function(user)
return user.name.toLowerCase().indexOf(q) != -1; // returns true or false
);
this.setState( filteredUsers: users );
render()
const userList = this.state.filteredUsers.map(user =>
return <li>user.name user.age</li>;
);
return (
<div>
<input
type="text"
placeholder="Search"
value=this.state.q
onChange=this.onChange
/>
<ul>
userList
</ul>
</div>
);
const userList = [
name: 'Raul',
age: 29
,
name: 'Mario',
age: 22
];
ReactDOM.render(<Test users=userList />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
【讨论】:
索引看起来如何? 你可以在那里做一个 if 语句。如果.indexOf(q)
的结果是-1
,则返回false。否则,返回真。或user.name.toLowerCase().indexOf(q) != -1
一行完成。
谢谢!只有一个问题!用户数组不断增长,因此当添加更多用户时,它们不会显示。你知道我怎么能解决这个问题吗?!
更新了我的答案。当组件接收到新的 props 时,您还想更新 filteredUsers
状态。此外,您可能希望根据您想要的行为再次手动调用filterList
。
这是我已经尝试过的,但这会破坏过滤器搜索,因为当将新用户添加到数组时会再次显示整个数组。明白我的意思吗?【参考方案2】:
您还需要一个state
变量来存储搜索结果,用相同的数据初始化该变量,一旦用户键入任何内容,将过滤后的数据存储在其中,试试这个:
let users = [
name: 'Raul',
age: 29
,
name: 'Mario',
age: 22
];
class Test extends React.Component
constructor(props)
super(props);
this.state =
users: users,
result: users,
;
this.filterList = this.filterList.bind(this);
componentWillReceiveProps(nextProps)
this.setState(
users: nextProps.users,
);
filterList(event)
let value = event.target.value;
let users = this.state.users, result=[];
result = users.filter((user)=>
return user.name.toLowerCase().search(value) != -1;
);
this.setState(result);
render()
const userList = this.state.result.map((user) =>
return <li>user.name user.age</li>;
);
return(<div>
<input type="text" placeholder="Search" onChange=this.filterList/>
<ul>
userList
</ul>
</div>
);
ReactDOM.render(<Test/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='app'></div>
【讨论】:
【参考方案3】:let datas =[
"id":1,
"title":"Ucat",
"handle":"mi"
,
"id":2,
"title":"Acat",
"handle":"csk"
,
"id":3,
"title":"Vcat",
"handle":"kkr"
,
"id":4,
"title":"Atar",
"handle":"pkbs"
];
const [search, setSearch] =useState(datas);
const handleInputChange = (e) =>
var dm = e.target.value;
var str =dm.toString();
var debug = datas.filter(x=> x["title"].toLowerCase().includes(str));
setSearch(debug);;
<input type="text" onChange=handleInputChange/>
search.map((item)=>(
<div key=item.id>
<ul>
<li>
item.handle
<br/>
item.title
</li>
</ul>
</div>
));
【讨论】:
发布答案时请提供相关解释,以便提问者更好地理解解决方案【参考方案4】:如果您想过滤列表,您必须有一个过滤条件。例如你有一个变量let filterAge = 18;
在这种情况下,您可以使用该值过滤用户列表
let users = users.filter(function(user)
//return all users older or equal to filterAge
return user.age >= filterAge;
);
函数的每个结果等于 true,都将添加到 users
变量中。虚假的回报将把它排除在外。如何确定真/假取决于您。硬编码它(不是很有用),一个简单的等号语句(如上)或一个做高等数学的函数。你的选择。
【讨论】:
codepen.io/pjmtokyo/pen/ZGVjVV 这个似乎是根据具体情况进行的,没有像if user is older than 18
那样明确的东西
你能看到search
是在哪里定义的吗?
好吧,他在这里指定使用函数来确定(小写)名称是否具有给定的值(小写),使用搜索功能。
啊是啊,不知道有一个js search
方法。随时更新你的答案,我可以给你一个绿色的勾
他正在使用默认的javascript字符串搜索功能。有关详细信息,请参阅w3schools.com/jsref/jsref_search.asp。如果该字符串包含给定值,则返回字符串中该值开始的位置。如果它在开头,则该值返回 0。如果它不在其中,则返回 -1。但总的来说,他将搜索值与过滤器函数中的每个项目进行匹配。【参考方案5】:
这样对我来说总是很有效。
const [data, setData] = useState([name: 'Kondo', name: 'Gintoki'])
const handleFilterFilesTable = () =>
return data
.filter((element) =>
if (searchText !== "")
return element?.name?.toLowerCase()?.includes(searchText?.toLowerCase())
return element
)
// ...
return (
//...
<Table data=handleFilterFilesTable() />
)
这样我就可以应用多个过滤器一起工作,只需像这样扩展 filter 方法
// ...
return data.filter().filter().filter()//...
// ...
【讨论】:
以上是关于数组 - Javascript - 使用输入搜索过滤对象数组的主要内容,如果未能解决你的问题,请参考以下文章