按 2 个键对结构数组进行排序

Sorting an array of structs by 2 keys

提问人:CFNinja 提问时间:9/28/2023 最后编辑:rrkCFNinja 更新时间:9/30/2023 访问量:83

问:

我有以下数据:

arTicker = [];
arTicker[1] = { "vid" : 100,
                "symbol" : "apple" };
arTicker[2] = { "vid" : 101,
                "symbol" : "dell" };
arTicker[3] = { "vid" : 102,
                "symbol" : "ibm" };                    
arTicker[4] = { "vid" : 110,
                "symbol" : "apple" };                        
arTicker[5] = { "vid" : 95,
                "symbol" : "apple" };                        
arTicker[6] = { "vid" : 115,
                "symbol" : "samsung" };    
arTicker[7] = { "vid" : 121,
                "symbol" : "dell" };      
arTicker[8] = { "vid" : 97,
                "symbol" : "apple" };    
arTicker[9] = { "vid" : 107,
                "symbol" : "ibm" };     

我正在尝试按符号名称对这个数组进行排序,并包括该符号的最大 vid。在这样做时,这是我想要的输出:

apple    | 110
dell     | 121
ibm      | 107
samsung  | 115  

这是我尝试过的

arraySort(
    arTicker,
    function (e1, e2){
        return compare(e1.symbol, e2.symbol) // && e1.vid < e2.vid;
    }
);
writeDump(arTicker); 

有什么建议吗?

冷融合

评论

0赞 Dan Bracuk 9/29/2023
这些数据的来源是什么?QofQ 是一种选择吗?

答:

2赞 rrk 9/28/2023 #1

这可能有点过分了。

<cfscript>
    arTicker = [];
    arTicker[1] = { "vid" : 100, "symbol" : "apple" };
    arTicker[2] = { "vid" : 101, "symbol" : "dell" };
    arTicker[3] = { "vid" : 102, "symbol" : "ibm" };                    
    arTicker[4] = { "vid" : 110, "symbol" : "apple" };                        
    arTicker[5] = { "vid" : 95, "symbol" : "apple" };                        
    arTicker[6] = { "vid" : 115, "symbol" : "samsung" };    
    arTicker[7] = { "vid" : 121, "symbol" : "dell" };      
    arTicker[8] = { "vid" : 97, "symbol" : "apple" };    
    arTicker[9] = { "vid" : 107, "symbol" : "ibm" };     
    tracker = [];
    zeroPadding = '0000';
    finalArray = arTicker
        .sort(
            function (e1, e2){
                return compare(
                    e1.symbol & '-' & numberFormat(e1.vid,zeroPadding),
                    e2.symbol & '-' & numberFormat(e2.vid,zeroPadding)
                );
            }
        )
        .reduce(
            function (shell, element){
                shell[element.symbol] = element;
                return shell;
            },
            structNew( "ordered" )
        ).reduce(
            function (shell, key, element){
                shell.append(element);
                return shell;
            },
            []
        );
    writeDump(finalArray); 
</cfscript>

我正在组合并将组合作为字符串进行比较。由于 是一个数字,我用它们填充它们以使其长度相同,因此作为字符串的数字不会引起问题。symbolvidvid0

然后从排序的数组中创建一个 using (struct 将包含符号组中的最后一项,即 .然后再次在结构上使用以取回数组。ordered structreducemax()reduce

演示

对于 Coldfusion 11,也有类似的解决方案。

//ArraySort mutates the array return true or false
ArraySort(
    arTicker,
    function (e1, e2){
        return compare(
            e1.symbol & '-' & numberFormat(e1.vid,zeroPadding),
            e2.symbol & '-' & numberFormat(e2.vid,zeroPadding)
        );
    }
);

finalArray = StructReduce(
    ArrayReduce(
        arTicker,
        function (shell, element){
            shell[element.symbol] = element;
            return shell;
        },
        {}
    ),
    function (shell, key, element){
        shell.append(element);
        return shell;
    },
    []
);

评论

0赞 CFNinja 9/28/2023
谢谢,但请看一下所需的输出。我可以这么说,我需要 max(vid)、symbol、group by symbol。
0赞 rrk 9/29/2023
@CFNinja,我做了一些更新。可能有用。
0赞 CFNinja 9/29/2023
忘了说我在 ColdFusion 11 上。不过很棒的解决方案。
0赞 rrk 9/30/2023
@CFNinja 这可能适用于 11。我没有要测试的环境。演示
0赞 CFNinja 9/30/2023
史诗!感谢一百万@rrk