按值重新排序JSON,显示a,b,c,a,b,c

时间:2015-02-21 00:06:32

标签: json sorting

我有一些JSON,格式如下。我希望有一个脚本重新安排它,以便按优先顺序排序,但使用交替值。例如,显示a,b,c,a,b,c。任何人都可以帮忙吗?

[   
    {
        "name" : "Tim",
        "preference" : "b"
    },
    {
        "name" : "Tom",
        "preference" : "b"
    },
    {
        "name" : "Steve",
        "preference" : "a"
    },
    {
        "name" : "Rick",
        "preference" : "a"
    },
    {
        "name" : "Nile",
        "preference" : "c"
    },
    {
        "name" : "James",
        "preference" : "c"
    }
]

1 个答案:

答案 0 :(得分:1)

Underscore提供适合此任务的实用程序。

首先,按首选项字段对输入进行分组:

var groups = _.groupBy(input, 'preference');

然后将其转换为数组数组:

var arrays = _.values(groups);

然后," zip"小组:

var result = _.zip.apply(null, arrays);

在一行中:

var result = _.zip.apply(null, _.values(_.groupBy(input, 'preference')));

非下划线版

如果您不想使用下划线,那么您必须编写自己的groupByzip版本:

function groupBy(array, prop) {
    var result = {};

    for (var i = 0; i < array.length; i++) {
        var entry = array[i];
        var val   = entry[prop];
        if (!result[val]) result[val] = [];
        result[val].push(entry);
    }

    return result;
}

这个或者下划线的_.groupBy会将您的输入转换为

{ 
    b: [ { name: 'Tim', preference: 'b' }, ... ],
    a: [ { name: 'Rick', preference: 'a' }, ... ]
}

获取数组的数组:

function values(obj) {
    return Object.keys(obj) . sort() . map(function(key) { return obj[key]; });
}

这将导致

[ 
    [ { name: 'Tim', preference: 'b' }, ... ],
    [ { name: 'Rick', preference: 'a' }, ... ]
]

然后是zip:

function zip(arrays) {
    var result = [];
    var n      = 0;
    var more   = true;
    var array;

    while (more) {
        more = false;
        for (var i = 0; i < arrays.length; i++) {
            array = arrays[i];
            if (n < array.length) {
                more = true;
                result.push(array[n]);
            }
        }
        n++;
    }
    return result;
}

注意:zip的这种实现将数组数组作为参数,与Underscore的版本不同,后者将数组作为单独的参数。

然后

zip(values(groupBy(input, 'preference')))