根据输入中的每个字母过滤数组

Posted

技术标签:

【中文标题】根据输入中的每个字母过滤数组【英文标题】:filtering array based on each letter from input 【发布时间】:2021-02-16 19:52:39 【问题描述】:

我正在根据来自文本框的输入过滤一组学生。当你输入名字时,我怎样才能让它向学生展示?我的解决方案有效,但显然,如果您要退格,学生数组不会重新填充。当您键入学生的姓名并在退格时重新填充数组时,我怎样才能让它过滤?

function App() 
  const [student, setStudent] = useState([]);

  useEffect(() => 
    fetch(api)
      .then((response) => response.json())
      .then((result) => 
        setStudent(result.students);
        
      )
      .catch((err) => 
        console.error(err);
      );
  , [setStudent]);

  const filter = (e) => 
    for (let i = 0; i < student.length; i++) 
      const searchedStudent = student.filter((name) => 
        return name.firstName.toLowerCase().includes(e.target.value);
      );

      setStudent(searchedStudent);
    
  ;

  return (
    <>
      <input
        placeholder="Search by name"
        type="text"
        className="filter-students"
        onChange=filter
      />
      student.map((students) => 
        let total = 0;
        for (let i = 0; i < students.grades.length; i++) 
          total += parseInt(students.grades[i]);
        

        const average = total / students.grades.length;
        console.log(average);

        return (
          <ul className="student-container">
            <img className="student-img" src=students.pic />

            <div className="student-column">
              <li className="student-item">
                " "
                students.firstName students.lastName
              </li>
              <li className="student-item">Email: students.email</li>
              <li className="student-item">Company: students.company</li>
              <li className="student-item">Skill: students.skill</li>

              <li className="student-item">Average: average%</li>
            </div>
          </ul>
        );
      )
    </>
  );

【问题讨论】:

【参考方案1】:

不要过滤您的状态并将其保存回来,这不会让您回到原来的状态。相反,使用单独的状态来保存过滤器值并在呈现状态时进行内联过滤,这样您就可以保持 student 数据完整且不会通过过滤而发生变化。

function App() 
  const [student, setStudent] = useState([]);
  const [filterValue, setfilterValue] = useState(""); // <-- filter state

  return (
    <>
      <input
        placeholder="Search by name"
        type="text"
        className="filter-students"
        onChange=(e) => setFilterValue(e.target.value) // <-- update filter state
      />
      student
        .filter((name) =>  // <-- filter inline
          return name.firstName.toLowerCase().includes(e.target.value);
        )
        .map((students) => 
          let total = 0;
          for (let i = 0; i < students.grades.length; i++) 
            total += parseInt(students.grades[i]);
          

          const average = total / students.grades.length;
          console.log(average);

          return (
            <ul className="student-container">
              <img className="student-img" src=students.pic />

              <div className="student-column">
                <li className="student-item">
                  " "
                  students.firstName students.lastName
                </li>
                <li className="student-item">Email: students.email</li>
                <li className="student-item">Company: students.company</li>
                <li className="student-item">Skill: students.skill</li>

                <li className="student-item">Average: average%</li>
              </div>
            </ul>
          );
        )
    </>
  );

【讨论】:

【参考方案2】:

问题是每次&lt;input&gt; 更改时,student 状态都会更新。

请注意,过滤结果为来自原始数据的派生数据。

因此,不需要将过滤/派生的结果存储为状态。

相反,您需要为用于过滤的文本设置另一种状态

const [student, setStudent] = useState([]);
const [filter, setFilter] = useState(""); // state for the text filter

<input
  placeholder="Search by name"
  type="text"
  className="filter-students"
  onChange=(e) => setFilter(e.target.value)
/>

students
  .filter((name) => name.firstName.toLowerCase().includes(filter)) // use filter state
  .map(/* Add elements here */)


【讨论】:

以上是关于根据输入中的每个字母过滤数组的主要内容,如果未能解决你的问题,请参考以下文章

根据 React 中的输入字段过滤对象数组

如何根据MongoDB中文档字段中的每个数组项过滤集合

使用数组过滤器打开报表

当过滤器为空时,它返回空数组

根据拼音首字母进行过滤的combobox

如何使用jq根据内部数组中的值过滤对象数组?