You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义sortData排序遇toLowerCase错误,求字符串转换排序方案

问题分析与解决

问题描述

尝试使用自定义的sortData函数对目标JSON数组排序,处理region字段时先通过JSON.parse解析,再拼接字符串存入新数组并JSON.stringify转回,但排序时触发"toLowerCase is not a function"错误,系统仍将输入识别为对象而非字符串。

自定义排序函数

export const sortData = (data, sortColumn, sortDirection) => {
  if (
    isNotNullOrUndefined(data) &&
    isNotNullOrUndefined(sortColumn) &&
    isNotNullOrUndefined(sortDirection)
  ) {
    data.sort((firstElement, secondElement) => {
      // Move null/empty values to last
      if (!isNotNullOrUndefined(firstElement[sortColumn]) || firstElement[sortColumn] === "") {
        return 1;
      }
      if (!isNotNullOrUndefined(secondElement[sortColumn]) || secondElement[sortColumn] === "") {
        return -1;
      }
      // Handle custom date sorting
      if (isCustomDate(firstElement[sortColumn]) && isCustomDate(secondElement[sortColumn])) {
        const milliSecValue1 = getMilliSecFromDateString(firstElement[sortColumn]);
        const milliSecValue2 = getMilliSecFromDateString(secondElement[sortColumn]);
        return sortDirection === "ascending"
          ? milliSecValue1 - milliSecValue2
          : milliSecValue2 - milliSecValue1;
      }
      // Handle numeric sorting
      if (isNumeric(firstElement[sortColumn]) && isNumeric(secondElement[sortColumn])) {
        const numValue1 = parseFloat(firstElement[sortColumn]);
        const numValue2 = parseFloat(secondElement[sortColumn]);
        return sortDirection === "ascending"
          ? numValue1 - numValue2
          : numValue2 - numValue1;
      }
      // Handle Text sorting
      if (firstElement[sortColumn].toLowerCase() < secondElement[sortColumn].toLowerCase()) {
        return sortDirection === "ascending" ? -1 : 1;
      }
      if (firstElement[sortColumn].toLowerCase() > secondElement[sortColumn].toLowerCase()) {
        return sortDirection === "ascending" ? 1 : -1;
      }
      return 0;
    });
  }
  return data;
};

目标JSON数组

[
  {
    "NA": {
      "Date": "2023-06-19",
      "Time": "13:01:00",
      "Timezone": "PST"
    }
  },
  {
    "EU": {
      "Date": "2023-06-19",
      "Time": "13:01:00",
      "Timezone": "GMT"
    }
  },
  {
    "IN": {
      "Date": "2023-06-19",
      "Time": "13:01:00",
      "Timezone": "IST"
    }
  }
]

原始处理代码

var regionsData = JSON.parse(element[0]["region"]);
var addRegionData = [];
regionsData.forEach((value) => {
  addRegionData.push(
    Object.keys(value).toString() +
      " " +
      value[Object.keys(value)[0]].Date +
      " " +
      value[Object.keys(value)[0]].Time +
      " " +
      value[Object.keys(value)[0]].Timezone +
      " "
  );
  dataObj.regions = [JSON.stringify(addRegionData)];
});

错误原因

  1. 数据结构错误:原始处理代码中dataObj.regions = [JSON.stringify(addRegionData)]将整个数组字符串化后放入一个新数组,导致sortData处理时,firstElement[sortColumn]指向的是包含整个数组字符串的元素,而非单个region的字符串;甚至如果sortColumn对应的值仍是原始对象,调用toLowerCase自然会报错。
  2. 类型未确保:sortData的文本排序部分未确保目标值是字符串类型,若传入的是对象或其他非字符串类型,调用toLowerCase会直接抛出错误。

修复方案

方案1:修正数据处理逻辑

先将原始JSON数组转换为sortData可直接处理的结构,每个元素包含明确的字符串类型字段:

// 假设regionsData是解析后的目标JSON数组
const processedData = regionsData.map(item => {
  const regionKey = Object.keys(item)[0];
  const regionInfo = item[regionKey];
  return {
    region: `${regionKey} ${regionInfo.Date} ${regionInfo.Time} ${regionInfo.Timezone}`
  };
});

// 此时调用sortData,sortColumn传入"region"
const sortedData = sortData(processedData, "region", "ascending");
  • 转换后每个元素是包含region字符串字段的对象,sortData读取firstElement["region"]时直接拿到字符串,可正常调用toLowerCase。

方案2:增强sortData的类型兼容性

在文本排序部分先将值转换为字符串,避免非字符串类型导致的错误:

export const sortData = (data, sortColumn, sortDirection) => {
  if (
    isNotNullOrUndefined(data) &&
    isNotNullOrUndefined(sortColumn) &&
    isNotNullOrUndefined(sortDirection)
  ) {
    data.sort((firstElement, secondElement) => {
      let val1 = firstElement[sortColumn];
      let val2 = secondElement[sortColumn];

      // Move null/empty values to last
      if (!isNotNullOrUndefined(val1) || val1 === "") {
        return 1;
      }
      if (!isNotNullOrUndefined(val2) || val2 === "") {
        return -1;
      }

      // 统一转换为字符串,避免类型错误
      val1 = String(val1);
      val2 = String(val2);

      // Handle custom date sorting
      if (isCustomDate(val1) && isCustomDate(val2)) {
        const milliSecValue1 = getMilliSecFromDateString(val1);
        const milliSecValue2 = getMilliSecFromDateString(val2);
        return sortDirection === "ascending"
          ? milliSecValue1 - milliSecValue2
          : milliSecValue2 - milliSecValue1;
      }
      // Handle numeric sorting
      if (isNumeric(val1) && isNumeric(val2)) {
        const numValue1 = parseFloat(val1);
        const numValue2 = parseFloat(val2);
        return sortDirection === "ascending"
          ? numValue1 - numValue2
          : numValue2 - numValue1;
      }
      // Handle Text sorting
      const lowerVal1 = val1.toLowerCase();
      const lowerVal2 = val2.toLowerCase();
      if (lowerVal1 < lowerVal2) {
        return sortDirection === "ascending" ? -1 : 1;
      }
      if (lowerVal1 > lowerVal2) {
        return sortDirection === "ascending" ? 1 : -1;
      }
      return 0;
    });
  }
  return data;
};
  • 提前将val1和val2转换为字符串,确保后续调用toLowerCase时不会因类型错误报错;同时后续的日期、数值判断也基于字符串进行,不影响原有逻辑。

完整示例

结合两种方案,处理并排序数据:

// 解析原始数据
const regionsData = JSON.parse(element[0]["region"]);
// 转换为标准结构
const processedData = regionsData.map(item => {
  const regionKey = Object.keys(item)[0];
  const regionInfo = item[regionKey];
  return {
    region: `${regionKey} ${regionInfo.Date} ${regionInfo.Time} ${regionInfo.Timezone}`
  };
});
// 使用增强后的sortData排序
const sortedData = sortData(processedData, "region", "ascending");

内容的提问来源于stack exchange,提问作者Zubair Amjad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 19:05:07