javascript 基于类别的对象Map与过滤

uqxowvwt  于 2023-04-04  发布在  Java
关注(0)|答案(2)|浏览(119)

我创建了一个简单的搜索项目页面
1.加载时,用户将看到其类别下的所有项目。
1.用户将能够搜索项目。
1.如果找到,将显示项目,否则将显示“无项目”。
然而,我仍然认为下面的代码没有优化,可以缩短,因为我可以看到每个类别Map的不情愿代码。
我很感激知道我应该如何使用一个过滤器和一个Map的SECTION TO OPTIMIZE下面。谢谢。
编码:https://codesandbox.io/s/beautiful-brahmagupta-79i9ih?file=/src/App.js

import React, { useEffect, useState } from "react";
import "./index.css";

const object = [
  { category: "One", name: "Mishanta" },
  { category: "One", name: "Virichia" },
  { category: "Two", name: "Steven" },
  { category: "Two", name: "Vikhostana" },
  { category: "Three", name: "Rockhosita" },
  { category: "Three", name: "Johnsonow" },
  { category: "Three", name: "Urvesta" },
  { category: "Two", name: "Dipuota" },
  { category: "One", name: "Dikhosta" }
];
const App = () => {
  const [searchedInput, setSearchedInput] = useState("");
  const [searchedItem, setSearchedItem] = useState([]);
  const [items, setItems] = useState([]);

  useEffect(() => {
    setItems(object);
  }, []);

  useEffect(() => {
    if (searchedInput !== "") {
      const arr = JSON.parse(JSON.stringify(object));
      const filteredData = arr.filter((value) => {
        const searchStr = searchedInput.replace(/\s/g, "").toLowerCase();
        const nameMatches = value.name.toLowerCase().includes(searchStr);
        return nameMatches;
      });
      setSearchedItem(filteredData);
    }
  }, [searchedInput]);

  return (
    <>
      <input type="text" onChange={(e) => setSearchedInput(e.target.value)} />

      {searchedInput.length > 0 ? (
        searchedItem.length == 0 ? (
          <h4>No item found. Sorry bro..</h4>
        ) : (
          searchedItem.map((x, i) => (
            <>
              <h4>Category: {x.category}</h4>
              <span key={i} className="selected-styles">
                {x.name}
              </span>
            </>
          ))
        )
      ) : (
        <>
          // SECTION TO OPTIMIZE
          <h4>Category: One</h4>
          {items
            .filter((item) => item.category === "One")
            .map((x, i) => (
              <span key={i} className="styles">
                {x.name}
              </span>
            ))}

          <hr />

          <h4>Category: Two</h4>
          {items
            .filter((item) => item.category === "Two")
            .map((x, i) => (
              <span key={i} className="styles">
                {x.name}
              </span>
            ))}

          <hr />

          <h4>Category: Three</h4>
          {items
            .filter((item) => item.category === "Three")
            .map((x, i) => (
              <span key={i} className="styles">
                {x.name}
              </span>
            ))}
        </>
      )}
    </>
  );
};

export default App;
dluptydi

dluptydi1#

如果可以的话,你可以对对象进行分组,比如说它总是基于这个属性。所以你可以从一些函数开始,它接受一个对象数组,并将它们分组到一个数组对象中,或者在这里我使用map,因为它可能更合适。

const groupBy = (arr, key) =>
  arr.reduce(
    (pre, curr) =>
      new Map(pre.set(curr[key], [...(pre.get(curr[key]) || []), curr])),
    new Map()
  );

然后,对于JSX部分,您可以调用函数

{[...groupBy(items, "category").entries()].map(
        ([category, items]) => (
          <>
            <h4>Category: {category}</h4>
            {items.map((item) => (
              <span key={item} className="styles">
                {item.name}
              </span>
            ))}
            <hr />
          </>
        )
      )}

这是一个更少的代码,适用于任何类别。最终,如果你想在分组方面有更大的灵活性,你可以用一个函数来代替key arg,该函数应该返回给定项目的组,但看看你拥有的数据,这似乎是一个很好的开始。
https://codesandbox.io/s/dazzling-swanson-81wufo?file=/src/App.js
最好的

2lpgd968

2lpgd9682#

您可以将公共过滤器提取到单独的功能组件,因为逻辑对于所有情况都是相同的。
你可以写一个像下面这样的通用功能组件,并将过滤条件作为参数传递。

const ItemsFilter = ({ items, type }) => {
 return (
  <>
  {items
    .filter((item) => item.category === type)
    .map((x, i) => (
      <span key={i} className="styles">
        {x.name}
      </span>
    ))}
  </>
 );
};

然后替换重复的过滤器并在其位置添加ItemsFilter组件。

<ItemsFilter items={items} type={"One"} />

modified codesandbox link

相关问题