【问题标题】:Positional sort of 2d Array [closed]二维数组的位置排序[关闭]
【发布时间】:2017-10-18 12:56:25
【问题描述】:

问题

我有一个二维数组,它实际上是输入到 Google 表格中的数据。它按逻辑排序,由用户定义。

目标是在该表的末尾输入新行,然后按位置排序。

说“按位置”是指“欧洲”排在“美国”之前,因为用户之前输入过。

这是用于测试的示例数组:

var data = 
  [
    ['Earth', 'Europe', 'Britain', 'London'],
    ['Earth', 'Europe', 'Britain', 'Manchester'],
    ['Earth', 'Europe', 'Britain', 'Liverpool'],
    ['Earth', 'Europe', 'France', 'Paris'],
    ['Earth', 'Europe', 'France', 'Lion'],
    ['Earth', 'Europe', 'Italy', 'Rome'],
    ['Earth', 'Europe', 'Italy', 'Milan'],
    ['Earth', 'Europe', 'Greece', 'Athenes'],
    ['Earth', 'Asia', 'China', 'Pekin'],
    ['Earth', 'Africa', 'Algeria', 'Algiers'],
    ['Earth', 'America', 'USA', 'Dallas'],
    ['Earth', 'America', 'USA', 'New York'],
    ['Earth', 'America', 'USA', 'Chicago'],
    ['Tatooine', 'Yulab', 'Putesh', 'ASU'],
    ['Tatooine', 'Yulab', 'Putesh', 'Niatirb'],
    ['Tatooine', 'Yulab', 'Zalip', 'Duantan'],
    ['Tatooine', 'Asia', 'Solo', 'Lion'],
    ['Tatooine', 'Asia', 'Solo', 'To'],
    ['Earth', 'America', 'USA', 'San Francisco'], 
    ['Tatooine', 'Yulab', 'Koko', 'Traiwau'],
    ['Venus', 'Yoo', 'Van', 'Derzar'],
    ['Tatooine', 'Chendoo', 'org', 'Eccel']
  ];

正确的结果数组是:

/*
  [  [Earth, Europe, Britain, London], 
     [Earth, Europe, Britain, Manchester], 
     [Earth, Europe, Britain, Liverpool], 
     [Earth, Europe, France, Paris], 
     [Earth, Europe, France, Lion], 
     [Earth, Europe, Italy, Rome], 
     [Earth, Europe, Italy, Milan], 
     [Earth, Europe, Greece, Athenes], 
     [Earth, Asia, China, Pekin], 
     [Earth, Africa, Algeria, Algiers], 
     [Earth, America, USA, Dallas], 
     [Earth, America, USA, New York], 
     [Earth, America, USA, Chicago], 
     [Earth, America, USA, San Francisco], 
     [Tatooine, Yulab, Putesh, ASU], 
     [Tatooine, Yulab, Putesh, Niatirb], 
     [Tatooine, Yulab, Zalip, Duantan], 
     [Tatooine, Yulab, Koko, Traiwau], 
     [Tatooine, Asia, Solo, Lion], 
     [Tatooine, Asia, Solo, To], 
     [Tatooine, Chendoo, org, Eccel], 
     [Venus, Yoo, Van, Derzar]
  ]
*/

我想为此使用脚本。

我的解决方案

我制作了自己的脚本版本,请看这里:

https://github.com/Max-Makhrov/positional-sorting/blob/master/main.js

算法的工作原理

该算法从第一行开始查找组:地球 > 欧洲 > 英国。然后它会尝试在以后的条目中找到该组的匹配项。

我还考虑为较早的条目分配更高的索引。

问题

问题:有没有更好的方法:

  1. 完成相同任务的代码更少
  2. 按位置对数组进行排序的更通用方法
  3. 需要足够快的解决方案,因为我将使用工作表中的代码,它有limits on script time

【问题讨论】:

  • @Luca,我已经编辑了问题并将其限制为确定适当的答案。能否请您重新打开它。我得到了正确答案,希望我的问题对其他用户有所帮助

标签: javascript sorting google-apps-script google-sheets grouping


【解决方案1】:

您可以使用sorting with map,其中每个组都会获得第一个找到的索引来对组进行排序。

稍后取最后一项映射回数组。

它适用于组的嵌套哈希表,例如

{
    Earth: {
        _: 0,
        Europe: {
            _: 0,
            Britain: {
                _: 0,
                London: {
                    _: 0
                },
                Manchester: {
                    _: 1
                },
                Liverpool: {
                    _: 2
                }
            },
            // ...
        },
        // ...
        America: {
            _: 10,
            USA: {
                _: 10,
                Dallas: {
                    _: 10
                },
                "New York": {
                    _: 11
                },
                Chicago: {
                    _: 12
                },
                "San Francisco": {
                    _: 18
                }
            }
        }
    }
}

其中每个属性_ 表示组的第一个索引。

排序用的临时数组是这样的,

//    index of group
//        index of group
//            index of group
//                own index
[
    [  0,  0,  0,  0 ],
    [  0,  0,  0,  1 ],
    [  0,  0,  0,  2 ],
    [  0,  0,  3,  3 ],
    [  0,  0,  3,  4 ],
    [  0,  0,  5,  5 ],
    [  0,  0,  5,  6 ],
    [  0,  0,  7,  7 ],
    [  0,  8,  8,  8 ],
    [  0,  9,  9,  9 ],
    [  0, 10, 10, 10 ],
    [  0, 10, 10, 11 ],
    [  0, 10, 10, 12 ],  // /_        moving between
    [ 13, 13, 13, 13 ],  // \ |       both items
    [ 13, 13, 13, 14 ],  //   |
    [ 13, 13, 15, 15 ],  //   |/_
    [ 13, 16, 16, 16 ],  //   |\ |
    [ 13, 16, 16, 17 ],  //   |  |/_
    [  0, 10, 10, 18 ],  // --+  |\ |
    [ 13, 13, 19, 19 ],  // -----+  |
    [ 20, 20, 20, 20 ],  //         |
    [ 13, 21, 21, 21 ]   // --------+ 
]

这用于对临时数组进行排序。

var data = [['Earth', 'Europe', 'Britain', 'London'], ['Earth', 'Europe', 'Britain', 'Manchester'], ['Earth', 'Europe', 'Britain', 'Liverpool'], ['Earth', 'Europe', 'France', 'Paris'], ['Earth', 'Europe', 'France', 'Lion'], ['Earth', 'Europe', 'Italy', 'Rome'], ['Earth', 'Europe', 'Italy', 'Milan'], ['Earth', 'Europe', 'Greece', 'Athenes'], ['Earth', 'Asia', 'China', 'Pekin'], ['Earth', 'Africa', 'Algeria', 'Algiers'], ['Earth', 'America', 'USA', 'Dallas'], ['Earth', 'America', 'USA', 'New York'], ['Earth', 'America', 'USA', 'Chicago'], ['Tatooine', 'Yulab', 'Putesh', 'ASU'], ['Tatooine', 'Yulab', 'Putesh', 'Niatirb'], ['Tatooine', 'Yulab', 'Zalip', 'Duantan'], ['Tatooine', 'Asia', 'Solo', 'Lion'], ['Tatooine', 'Asia', 'Solo', 'To'], ['Earth', 'America', 'USA', 'San Francisco'], ['Tatooine', 'Yulab', 'Koko', 'Traiwau'], ['Venus', 'Yoo', 'Van', 'Derzar'], ['Tatooine', 'Chendoo', 'org', 'Eccel']],
    hash = Object.create(null),
    result = data
        .map(function (a, i) {
            var temp = hash;
            return a.map(function (k) {
                temp[k] = temp[k] || { _: i };
                temp = temp[k];
                return temp._;
            });
        })
        .sort(function (a, b) {
            var value;
            a.some(function (v, i) {
                return value = v - b[i];
            });
            return value;
        })
        .map(function (indices) {
            return data[indices[indices.length - 1]];
        });

console.log(result.map(function (a) { return a.join(', '); }));
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 谢谢!这段代码很漂亮,但它给了我一个字母顺序,而不是位置。
  • 在这种情况下是什么意思?
  • 表示“Europe”排在“America”之前,因为用户之前输入过。
  • @MaxMakhrov 算法应该如何知道后面添加了哪些行?一些未排序的可能已经在逻辑上排序了。
  • @MaxMakhrov,请查看编辑,它现在按第一组排序。
猜你喜欢
  • 1970-01-01
  • 2020-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-06
  • 2012-10-11
相关资源
最近更新 更多