使用Lodash和React排序数字字符串?

问题描述 投票:0回答:1

我正在对表格中的列进行排序。我的文字专栏排序很好,而数字专栏则不好。

[当我尝试使用数字对数据进行排序时,会看到以下内容。这只是一个例子:

watchCount: ["2"]

此外,某些项目没有我需要的某些字段,在这种情况下,我仅显示0。可以在下面看到。

这是我要在其中映射数据的表。我还试图将parseInt()包含在数值数据中,但这无济于事。我正在尝试复制此示例:semantic ui react sort

我只是无法判断我在这里的排序是否做错了,还是因为它是一个字符串而无法排序。

 <Table sortable celled fixed striped>
          <Table.Header>
            <Table.Row>
              <Table.HeaderCell
                sorted={column === "title" ? direction : null}
                onClick={() => handleSort("title")}
              >
                Card Title
              </Table.HeaderCell>
              <Table.HeaderCell
                sorted={column === "bids" ? direction : null}
                onClick={() => handleSort("bids")}
              >
                # Bids
              </Table.HeaderCell>
              <Table.HeaderCell
                sorted={column === "watch" ? direction : null}
                onClick={() => handleSort("watch")}
              >
                Watchers
              </Table.HeaderCell>
              <Table.HeaderCell
                sorted={column === "price" ? direction : null}
                onClick={() => handleSort("price")}
              >
                Price
              </Table.HeaderCell>
              <Table.HeaderCell
                sorted={column === "time" ? direction : null}
                onClick={() => handleSort("time")}
              >
                Time Left
              </Table.HeaderCell>
            </Table.Row>
          </Table.Header>
          <Table.Body>
            {_.map(filteredData, card => (
              <>
                <Table.Row key={card.id}>
                  <Table.Cell>{card.title}</Table.Cell>
                  <Table.Cell>
                    {parseInt(
                      card.sellingStatus[0].bidCount
                        ? card.sellingStatus[0].bidCount
                        : 0
                    )}
                  </Table.Cell>
                  <Table.Cell>
                    {parseInt(
                      card.listingInfo[0].watchCount
                        ? card.listingInfo[0].watchCount
                        : 0
                    )}
                  </Table.Cell>
                  <Table.Cell>
                    $
                    {parseInt(
                      card.sellingStatus &&
                        card.sellingStatus[0].currentPrice[0]["__value__"]
                    )}
                  </Table.Cell>
                  <Table.Cell>
                    <TimeAgo
                      date={new Date(
                        card.listingInfo && card.listingInfo[0].endTime
                      ).toLocaleDateString()}
                    />
                  </Table.Cell>
                </Table.Row>
              </>
            ))}
          </Table.Body>
        </Table>

注意,这也是我的handleSort函数

 const [column, setColumn] = useState(null);
  const [direction, setDirection] = useState(null);
  const [filteredData, setData] = useState(props.cardsToShow);

  console.log("CARDS TO SHOW", props.cardsToShow);
  console.log("TYPE OF", typeof cardsToShow);
  console.log("Filtered Data", filteredData);
  console.log("column", column);
  console.log("direction", direction);

  const handleSort = clickedColumn => {
    if (column !== clickedColumn) {
      setColumn(clickedColumn);
      setData(_.sortBy(filteredData, [clickedColumn]));
      setDirection("ascending");
      return;
    }

    setData(_.sortBy(filteredData.reverse()));
    direction === "ascending"
      ? setDirection("descending")
      : setDirection("ascending");
  };

已编辑代码

const handleSortNumeric = clickedColumn => {
    const sorter = data => ~~data[clickedColumn];
    setData(_.sortBy(filteredData, sorter));
  };

  const handleSortReverse = () => {
    const sorter = data => ~~data;
    setData(_.sortBy(filteredData.reverse(), sorter));
  };

  const handleSort = clickedColumn => {
    if (column !== clickedColumn) {
      setColumn(clickedColumn);
      // setData(_.sortBy(filteredData, [clickedColumn]));
      handleSortNumeric(clickedColumn);
      setDirection("ascending");
      return;
    }

    // setData(_.sortBy(filteredData.reverse()));
    handleSortReverse();
    direction === "ascending"
      ? setDirection("descending")
      : setDirection("ascending");
  };
javascript reactjs redux lodash semantic-ui
1个回答
1
投票

排序字符串将遵循Unicode的顺序,它们按字符出现,而不是一个数字。因此,在对“ 40”和“ 5”进行排序时,您会期望“ 5”排在最前面,但“ 40”中的“ 4”是它所比较并输的。

请参阅此处了解更多详细信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

就直接解决问题而言,您可以将_.sortBy()作为第二个参数传递给函数,并在函数中将值转换为数字(使用~~Number()parseInt()等)避免字符串比较。

由于您似乎已经对这些代码进行了硬编码,因此也可以使用单独的handleSort函数来分离问题:

const handleSortNumeric = ( clickedColumn ) => {
    // ...

    const sorter = data => ~~data[ clickedColumn ];
    setData(_.sortBy(filteredData, sorter));

    // ...
};

但是,如果您可以控制如何从服务器呈现数据,则应提供正确键入的数据,以免将来发生此类情况

© www.soinside.com 2019 - 2024. All rights reserved.