JavaScript Array Sort with Mixed Value Types - 寻找合适的比较函数

卓越英雄

请参考下表。

我的目标是对包含混合数据类型的 JavaScript 数组进行排序:数字、字符串、布尔值、日期和未定义值。

这不是一种自然的排序。相反,我需要尽可能匹配 MS Excel 使用的排序顺序……。

这是一个 JavaScript ES5 问题,但数据是通过 VBA 中的数组来自 Excel。

该平台是托管在 Excel VBA 用户窗体中的 MS WebBrowser 控件 (IE11)。

我知道这是相当深奥的,但希望最终的问题不是。

Microsoft 的 JavaScript 风格有一个称为VBArray 对象的语言扩展,它有一个方法可用于将传递的 VB 安全数组转换为普通的 JavaScript 数组:

function convertVBArray(safearray){return new VBArray(safearray).toArray()}    

.toArray()方法执行转换,包括每个元素的数据类型转换。VBA 数组是 Variant 类型(标记联合),它支持许多不同的变量数据子类型。.toArray()方法完成将这些转换为 JavaScript 更有限的数据类型调色板的工作。

下表显示了 23 个值。想象一下它们在 Excel 的一列中。我从该列填充 VBA 变体数组(看起来像您Excel Displays在下表列中看到的内容

接下来的两列显示了数据在 VBA 数组中的样子。

接下来的三列显示了数据在转换为带有 .js 的 JavaScript 数组后的样子convertVBArray()

接下来,我使用以下比较函数对 JavaScript 数组进行排序:

a.sort(function (a, b) { return isNaN(a) ? isNaN(b) ? a.localeCompare(b) : 1 : isNaN(b) ? -1 : parseFloat(a) - parseFloat(b) })

...但这效果不佳。

请参阅JS sortArray()下表列。数据按照上述排序后返回的顺序呈现。

我正在寻找对比较函数的更改,以便它尽可能地与表中的下一列Excel Sort ASC.

最后,我还希望能够模拟最后一列中所示的反向排序,Excel Sort DESC.

我意识到各种错误值会转换为undefinedJavaScript 中的值,并且可能对此无能为力。我确实喜欢它们都排在排序列表的底部。


总而言之,我希望来自的值Excel Displays按 .js 中显示的顺序由 JavaScript 排序Excel Sort ASC但是我当前的比较函数产生了在JS sortArray().

我当前的比较功能无法按所需顺序排序

.

下表描述了数据和数据类型在从 Excel 传递到 VBA 到 JavaScipt 并返回到 Excel 时如何变化。

+-----+---------------+------------------------------+-----------------+-----------------------+----------------------+--------------+------------------------------------------------------------+-----------------------+----------------+-----------------+-----------------+
| Row | Excel Entered |     Excel Number Format      | Excel Displays  |    VBA Array Value    | VBA Array Value Type | JS Array Ndx |                       JS Array Value                       | JS Array Value typeof | JS sortArray() | Excel Sort ASC  | Excel Sort DESC |
+-----+---------------+------------------------------+-----------------+-----------------------+----------------------+--------------+------------------------------------------------------------+-----------------------+----------------+-----------------+-----------------+
|   1 | anchorage     | General                      | anchorage       | anchorage             | 8 - vbString         |            0 | anchorage                                                  | string                | -78.96         | -78.96          | #NAME?          |
|   2 | 123           | General                      | 123             | 123                   | 5 - vbDouble         |            1 | 123                                                        | number                | 123            | -1              | #N/A            |
|   3 | FALSE         | General                      | FALSE           | False                 | 11 - vbBoolean       |            2 | false                                                      | boolean               | FALSE          | 0               | #DIV/0!         |
|   4 | =qqq          | General                      | #NAME?          | Error 2029            | 10 - vbError         |            3 | undefined                                                  | undefined             | -1             | 0.60625         | TRUE            |
|   5 | 0             | 0.000_);[Red](0.000)         | 0               | 0                     | 5 - vbDouble         |            4 | 0                                                          | number                | 0              | 1               | FALSE           |
|   6 | 43514.49663   | m/d/yyyy h:mm                | 2/18/2019 11:55 | 2/18/2019 10:59:03 AM | 7 - vbDate           |            5 | Mon Feb 18 2019 11:59:09 GMT-0800 (Pacific Standard Time)  | date                  | 43514.49663    | 99.01           | zimmer          |
|   7 | =NA()         | General                      | #N/A            | Error 2042            | 10 - vbError         |            6 | undefined                                                  | undefined             | 0.60625        | 123             | Major Tom       |
|   8 | 99.01         | $#,##0.00_);[Red]($#,##0.00) | 99.01           | 99.01                 | 6 - vbCurrency       |            7 | 99.01                                                      | number                | 1              | 3/20/2017       | anchorage       |
|   9 |               | General                      |                 |                       | 0 - vbEmpty          |            8 | undefined                                                  | undefined             | 99.01          | 2/18/2019 11:55 | ABC             |
|  10 | =1/0          | General                      | #DIV/0!         | Error 2007            | 10 - vbError         |            9 | undefined                                                  | undefined             | 888.87         |                 | 888.87          |
|  11 | =""           | General                      |                 |                       | 8 - vbString         |           10 |                                                            | string                |                | $%^%$^          | $%^%$^          |
|  12 | ABC           | @                            | ABC             | ABC                   | 8 - vbString         |           11 | ABC                                                        | string                | TRUE           | 888.87          |                 |
|  13 | -78.96        | General                      | -78.96          | -78.96                | 5 - vbDouble         |           12 | -78.96                                                     | number                | 42814          | ABC             | 2/18/2019 11:55 |
|  14 | Major Tom     | @                            | Major Tom       | Major Tom             | 8 - vbString         |           13 | Major Tom                                                  | string                | $%^%$^         | anchorage       | 3/20/2017       |
|  15 | TRUE          | General                      | TRUE            | True                  | 11 - vbBoolean       |           14 | true                                                       | boolean               | ABC            | Major Tom       | 123             |
|  16 | =TODAY()-700  | m/d/yyyy                     | 3/20/2017       | 3/20/2017             | 7 - vbDate           |           15 | Mon Mar 120 2017 00:00:00 GMT-0700 (Pacific Standard Time) | date                  | anchorage      | zimmer          | 99.01           |
|  17 | zimmer        | General                      | zimmer          | zimmer                | 8 - vbString         |           16 | zimmer                                                     | string                | Major Tom      | FALSE           | 1               |
|  18 | 1             | General                      | 1               | 1                     | 5 - vbDouble         |           17 | 1                                                          | number                | zimmer         | TRUE            | 0.60625         |
|  19 |               | General                      |                 |                       | 0 - vbEmpty          |           18 | undefined                                                  | undefined             |                | #NAME?          | 0               |
|  20 | =0-1          | General                      | -1              | -1                    | 5 - vbDouble         |           19 | -1                                                         | number                |                | #N/A            | -1              |
|  21 | 0.60625       | h:mm                         | 0.60625         | 0.60625               | 5 - vbDouble         |           20 | 0.60625                                                    | number                |                | #DIV/0!         | -78.96          |
|  22 | ="888.87"     | General                      | 888.87          | 888.87                | 8 - vbString         |           21 | 888.87                                                     | string                |                |                 |                 |
|  23 | $%^%$^        | General                      | $%^%$^          | $%^%$^                | 8 - vbString         |           22 | $%^%$^                                                     | string                |                |                 |                 |
+-----+---------------+------------------------------+-----------------+-----------------------+----------------------+--------------+------------------------------------------------------------+-----------------------+----------------+-----------------+-----------------+

这里只是 JavaScript 数组和目标排序顺序:

+--------------+------------------------------------------------------------+-----------------------+-------------------+
| JS Array Ndx |                       JS Array Value                       | JS Array Value typeof | TARGET SORT ORDER |
+--------------+------------------------------------------------------------+-----------------------+-------------------+
|            0 | anchorage                                                  | string                | -78.96            |
|            1 | 123                                                        | number                | -1                |
|            2 | false                                                      | boolean               | 0                 |
|            3 | undefined                                                  | undefined             | 0.60625           |
|            4 | 0                                                          | number                | 1                 |
|            5 | Mon Feb 18 2019 11:59:09 GMT-0800 (Pacific Standard Time)  | date                  | 99.01             |
|            6 | undefined                                                  | undefined             | 123               |
|            7 | 99.01                                                      | number                | 3/20/2017         |
|            8 | undefined                                                  | undefined             | 2/18/2019 11:55   |
|            9 | undefined                                                  | undefined             |                   |
|           10 |                                                            | string                | $%^%$^            |
|           11 | ABC                                                        | string                | 888.87            |
|           12 | -78.96                                                     | number                | ABC               |
|           13 | Major Tom                                                  | string                | anchorage         |
|           14 | true                                                       | boolean               | Major Tom         |
|           15 | Mon Mar 120 2017 00:00:00 GMT-0700 (Pacific Standard Time) | date                  | zimmer            |
|           16 | zimmer                                                     | string                | false             |
|           17 | 1                                                          | number                | true              |
|           18 | undefined                                                  | undefined             | undefined         |
|           19 | -1                                                         | number                | undefined         |
|           20 | 0.60625                                                    | number                | undefined         |
|           21 | 888.87                                                     | string                | undefined         |
|           22 | $%^%$^                                                     | string                | undefined         |
+--------------+------------------------------------------------------------+-----------------------+-------------------+
基思

我认为这就像你所追求的那样。

在你的 JS 数组值 typeOf 中,它说日期是一个日期类型,但在普通的 Javascript 中typeof new Date()会给你对象,所以在你的情况下你可能想要更改为date.

我在这里所做的是创建一个复合排序,首先我们按 排序typeof,如果 a 和 b 的类型相同,则返回值为 0,这是您执行复合排序的第二部分,您是在这里保证 a & b 是相同的类型,所以只需根据类型进行适当的排序。

下面是一个工作片段,您可以运行以查看结果。

var data = [
 "anchorage",
  123,
  false,
  undefined,
  0,
  new Date("Mon Feb 18 2019 11:59:09 GMT-0800"),
  undefined,
  99.01,
  undefined,
  undefined,
  "",
  "ABC",
  -78.96,
  "Major Tom",
  true,
  new Date("Mon Mar 12 2017 00:00:00 GMT-0700"),
  "zimmer",
  1,
  undefined,
  -1,
  0.60625,
  "888.87",
  "$%^%$^"    
];

//what ordering do we want our types?.
var typesort = [
  "number", "object" /*date*/, "string", "boolean", "undefined"
];

data.sort(function (a, b) {
  //first lets sort by type
  var r = typesort.indexOf(typeof a) - typesort.indexOf(typeof b);
  if (r === 0) {
    //types are the same, need compound sort
    if (typeof a === "object") return a.getTime() - b.getTime()
    else if (typeof a === "string") return a.localeCompare(b)
    else return a - b;
  }
  return r;
});

console.log(data);

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

javascript函数BiggerOf(array,value)

来自分类Dev

Array.sort() 比较函数返回未定义

来自分类Dev

how to sort an array by a selected value in perl

来自分类Dev

Sort An array with its specified key value PHP

来自分类Dev

使用带有两个值的箭头函数,例如 Array.sort Javascript

来自分类Dev

返回键的javascript sort函数

来自分类Dev

返回键的javascript sort函数

来自分类Dev

使用sort函数和递归比较器对boost的multi_array进行排序

来自分类Dev

使用带有比较函数的 Array.prototype.sort() 时的排序算法是什么

来自分类Dev

获取单个比较函数以使用 Array.sort() 对 ASC 和 DESC 进行排序?

来自分类Dev

带有多重键的JavaScript Array.sort()

来自分类Dev

Javascript:在特定的数组结构上使用array.sort()

来自分类Dev

为什么array.sort在javascript中不起作用?

来自分类Dev

javascript:Array.sort() 在大型数组上是否会失败?

来自分类Dev

猫鼬:使用Schema.Types.Mixed动态创建键

来自分类Dev

猫鼬和Schema.Types.Mixed出现问题

来自分类Dev

猫鼬:使用Schema.Types.Mixed动态创建键

来自分类Dev

array.sort()方法中反向比较功能背后的逻辑

来自分类Dev

.sort() 二维数组 javascript 比较第二项

来自分类Dev

javascript sort,比较3种不同的类型并按顺序排序

来自分类Dev

Struct value types in Swift

来自分类Dev

JavaScript arguments.sort()引发错误排序不是函数

来自分类Dev

Sort an array of dictionaries in Swift

来自分类Dev

JavaScript Array.sort在某些数字数组上不起作用

来自分类Dev

如何在javascript中对合并2数组进行排序(如c#(Array.sort()))

来自分类Dev

JavaScript Array.prototype.sort()不能在DOM.HTMLLIElements上调用

来自分类Dev

detecting an existing string value within an array using jquery or javascript

来自分类Dev

JavaScript .sort覆盖

来自分类Dev

Using std::sort to sort an array of C strings

Related 相关文章

  1. 1

    javascript函数BiggerOf(array,value)

  2. 2

    Array.sort() 比较函数返回未定义

  3. 3

    how to sort an array by a selected value in perl

  4. 4

    Sort An array with its specified key value PHP

  5. 5

    使用带有两个值的箭头函数,例如 Array.sort Javascript

  6. 6

    返回键的javascript sort函数

  7. 7

    返回键的javascript sort函数

  8. 8

    使用sort函数和递归比较器对boost的multi_array进行排序

  9. 9

    使用带有比较函数的 Array.prototype.sort() 时的排序算法是什么

  10. 10

    获取单个比较函数以使用 Array.sort() 对 ASC 和 DESC 进行排序?

  11. 11

    带有多重键的JavaScript Array.sort()

  12. 12

    Javascript:在特定的数组结构上使用array.sort()

  13. 13

    为什么array.sort在javascript中不起作用?

  14. 14

    javascript:Array.sort() 在大型数组上是否会失败?

  15. 15

    猫鼬:使用Schema.Types.Mixed动态创建键

  16. 16

    猫鼬和Schema.Types.Mixed出现问题

  17. 17

    猫鼬:使用Schema.Types.Mixed动态创建键

  18. 18

    array.sort()方法中反向比较功能背后的逻辑

  19. 19

    .sort() 二维数组 javascript 比较第二项

  20. 20

    javascript sort,比较3种不同的类型并按顺序排序

  21. 21

    Struct value types in Swift

  22. 22

    JavaScript arguments.sort()引发错误排序不是函数

  23. 23

    Sort an array of dictionaries in Swift

  24. 24

    JavaScript Array.sort在某些数字数组上不起作用

  25. 25

    如何在javascript中对合并2数组进行排序(如c#(Array.sort()))

  26. 26

    JavaScript Array.prototype.sort()不能在DOM.HTMLLIElements上调用

  27. 27

    detecting an existing string value within an array using jquery or javascript

  28. 28

    JavaScript .sort覆盖

  29. 29

    Using std::sort to sort an array of C strings

热门标签

归档