混合值类型的JavaScript数组排序-寻找合适的比较函数
请参考下表 我的目标是对包含混合数据类型的JavaScript数组进行排序:数字、字符串、布尔值、日期和未定义的值 这不是一种自然现象。相反,我需要匹配MS Excel使用的排序顺序。。。尽可能接近 这是一个JavaScript ES5问题,但数据是通过VBA中的数组从Excel中获取的 该平台是MS WebBrowser控件(IE11),托管在Excel VBA用户表单中 这是相当深奥的,我知道,但希望最终的问题不是 Microsoft的JavaScript风格有一个名为的语言扩展,该扩展有一个方法,可用于将传递的VB安全数组转换为普通JavaScript数组:混合值类型的JavaScript数组排序-寻找合适的比较函数,javascript,internet-explorer-11,ecmascript-5,Javascript,Internet Explorer 11,Ecmascript 5,请参考下表 我的目标是对包含混合数据类型的JavaScript数组进行排序:数字、字符串、布尔值、日期和未定义的值 这不是一种自然现象。相反,我需要匹配MS Excel使用的排序顺序。。。尽可能接近 这是一个JavaScript ES5问题,但数据是通过VBA中的数组从Excel中获取的 该平台是MS WebBrowser控件(IE11),托管在Excel VBA用户表单中 这是相当深奥的,我知道,但希望最终的问题不是 Microsoft的JavaScript风格有一个名为的语言扩展,该扩展有一
function convertVBArray(safearray){return new VBArray(safearray).toArray()}
a.sort(function (a, b) { return isNaN(a) ? isNaN(b) ? a.localeCompare(b) : 1 : isNaN(b) ? -1 : parseFloat(a) - parseFloat(b) })
.toArray()
方法进行转换,包括每个元素的数据类型转换。VBA数组的类型为Variant(标记的联合),它支持许多不同的变量数据子类型。.toArray()
方法将这些转换为JavaScript更有限的数据类型调色板
下表显示了23个值。想象它们在Excel中的一列中。我从该列中填充VBA变量数组(与下表中Excel显示的列类似)
接下来的两列显示了数据在VBA数组中的外观
接下来的三列显示了使用convertVBArray()
转换为JavaScript数组后数据的外观
接下来,我使用以下比较函数对JavaScript数组进行排序:
function convertVBArray(safearray){return new VBArray(safearray).toArray()}
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
最后,我还希望能够模拟上一列中所示的反向排序,excelsortdesc
我意识到各种错误值在JavaScript中被转换为未定义的值,对此可能无能为力。我很喜欢它们都位于排序列表的底部
总之,我希望通过JavaScript按照Excel Sort ASC
中显示的顺序对Excel显示的值进行排序。但是,我当前的比较函数产生了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中,它表示date是一个类型date,但在普通Javascript中,typeOf new date()
将为您提供对象,因此在您的情况下,您可能需要更改为date
我在这里所做的是创建一个复合排序,首先我们按照类型进行排序,如果a和b都是相同的类型,则返回值为0,这是进行复合排序的第二部分,这里保证a和b是相同的类型,因此只需根据类型进行适当的排序
下面是一个工作代码段,您可以运行它来查看结果
var数据=[
“安克雷奇”,
123,
假,,
未定义,
0,
新日期(“2019年2月18日星期一11:59:09 GMT-0800”),
未定义,
99.01,
未定义,
未定义,
"",
“ABC”,
-78.96,
“汤姆少校”,
是的,
新日期(“2017年3月12日星期一00:00:00 GMT-0700”),
“齐默”,
1.
未定义,
-1,
0.60625,
"888.87",
"$%^%$^"
];
//我们想要什么样的型号?。
变量类型排序=[
“数字”、“对象”/*date*/、“字符串”、“布尔值”、“未定义”
];
数据排序(函数(a,b){
//首先让我们按类型排序
var r=typesort.indexOf(typeof a)-typesort.indexOf(typeof b);
如果(r==0){
//类型相同,需要复合排序
if(typeof a==“object”)返回a.getTime()-b.getTime()
else if(typeof a==“string”)返回a.localeCompare(b)
否则返回a-b;
}
返回r;
});
console.log(数据);
我认为这与您所追求的类似
在JS数组值typeOf中,它表示date是一个类型date,但在普通Javascript中,typeOf new date()
将为您提供对象,因此在您的情况下,您可能需要更改为date
我在这里所做的是创建一个复合排序,首先我们按照类型进行排序,如果a和b都是相同的类型,则返回值为0,这是进行复合排序的第二部分,这里保证a和b是相同的类型,因此只需根据类型进行适当的排序
下面是一个工作代码段,您可以运行它来查看结果
var数据=[
“安克雷奇”,
123,
假,,
未定义,
0,
新日期(“2019年2月18日星期一11:59:09 GMT-0800”),
未定义,
99.01,
未定义,
未定义,
"",
“ABC”,
-78.96,
“汤姆少校”,
是的,
新日期(“2017年3月12日星期一00:00:00 GMT-0700”),
“齐默”,
1.
未定义,
-1,
0.60625,
"888.87",
"$%^%$^"
];
//我们想要什么样的型号?。
变量类型排序=[
“数字”、“对象”/*date*/、“字符串”、“布尔值”、“未定义”
];
数据排序(函数(a,b){
//首先让我们按类型排序
var r=typesort.indexOf(typeof a)-typesort.indexOf(typeof b);
如果(r==0){
//类型相同,需要复合排序
if(typeof a==“object”)返回a.getTime()-b.getTime()
else if(typeof a==“string”)返回a.localeCompare(b)
否则返回a-b;
}
返回r;