Javascript 导出最高10个值的子集数组的最简单方法?

Javascript 导出最高10个值的子集数组的最简单方法?,javascript,Javascript,在javascript中,我有一个数组,如下所示: var foo = [2, 2, 4, 4, 128, 2, 2, 1, 4, 18, 27, 16, 2, 1, 18, 21, 5, 1, 128, 1, 2, 2, 1, 18, 12, 60, 2, 28, 1, 17, 2, 3, 4, 2, 2, 2, 1, 27, 2, 17, 7, 2, 2, 2, 5, 1, 2, 4, 7, 1, 2, 1, 1, 1, 2, 1, 5, 7, 2, 7, 6, 1, 7, 1, 5, 8,

在javascript中,我有一个数组,如下所示:

var foo = [2, 2, 4, 4, 128, 2, 2, 1, 4, 18, 27, 16, 2, 1, 18, 21, 5, 1, 128, 1, 2, 2, 1, 18, 12, 60, 2, 28, 1, 17, 2, 3, 4, 2, 2, 2, 1, 27, 2, 17, 7, 2, 2, 2, 5, 1, 2, 4, 7, 1, 2, 1, 1, 1, 2, 1, 5, 7, 2, 7, 6, 1, 7, 1, 5, 8, 4];
我感兴趣的是找到一种方法(在一个循环中,而不是在多个循环中)来导出最高10个值的子集数组,其中值的前一个位置是“键”(因此模拟贴图对象):

例如:


这是我先前答案的除错版本,使用索引表。我做了一点基准测试,对于问题中给出的输入,这个孤子将比这个线程中迄今为止建议的任何其他东西都要快:

var foo = [2, 2, 4, 4, 128, 2, 2, 1, 4, 18, 27, 16, 2, 1, 18, 21, 5, 1, 128, 1, 2, 2, 1, 18, 12, 60, 2, 28, 1, 17, 2, 3, 4, 2, 2, 2, 1, 27, 2, 17, 7, 2, 2, 2, 5, 1, 2, 4, 7, 1, 2, 1, 1, 1, 2, 1, 5, 7, 2, 7, 6, 1, 7, 1, 5, 8, 4];

var indexTable = {}, uniqueValues = [];

// --- build reverse index table, find unique values

for(var i = foo.length; i--; ) {
    var value = foo[i];
    if(indexTable.hasOwnProperty(value))
        indexTable[value].push(i);
    else {
        indexTable[value] = [i];
        uniqueValues.push(value);
    }
}

// --- sort unique values in ascending order

uniqueValues.sort(function(i1, i2) {
    return i1 - i2;
});

// --- find ten greatest values

var fooTopTen = [], k = 0;

for(var i = uniqueValues.length; k < 10 && i--; ) {
    var value = uniqueValues[i],
        indices = indexTable[value];

    for(var j = indices.length; k < 10 && j--; )
        fooTopTen[k++] = [indices[j], value];
}

// --- output result

document.writeln('[[' + fooTopTen.join('], [') + ']]');
var foo=[2,2,4,4,128,2,2,1,4,128,2,2,1,18,21,5,1,128,1,2,2,2,1,18,12,60,2,28,1,17,2,3,4,2,2,2,1,27,2,17,2,2,2,5,1,2,4,7,1,2,1,1,2,1,1,5,2,7,8,4];
var indexTable={},uniqueValues=[];
//---构建反向索引表,查找唯一值
for(var i=foo.length;i--;){
var值=foo[i];
if(indexTable.hasOwnProperty(value))
可索引[值]。推送(i);
否则{
可索引[值]=[i];
uniqueValues.push(值);
}
}
//---按升序对唯一值进行排序
uniqueValues.sort(函数(i1,i2){
返回i1-i2;
});
//---找出十大价值观
var fooTopTen=[],k=0;
对于(var i=uniqueValues.length;k<10&&i--;){
var值=唯一值[i],
指数=可索引[值];
对于(var j=index.length;k<10&&j--;)
fooTopTen[k++]=[指数[j],值];
}
//---输出结果
document.writeln('['+fooTopTen.join('],[')+']]);

这是我先前答案的除错版本,使用索引表。我做了一点基准测试,对于问题中给出的输入,这个孤子将比这个线程中迄今为止建议的任何其他东西都要快:

var foo = [2, 2, 4, 4, 128, 2, 2, 1, 4, 18, 27, 16, 2, 1, 18, 21, 5, 1, 128, 1, 2, 2, 1, 18, 12, 60, 2, 28, 1, 17, 2, 3, 4, 2, 2, 2, 1, 27, 2, 17, 7, 2, 2, 2, 5, 1, 2, 4, 7, 1, 2, 1, 1, 1, 2, 1, 5, 7, 2, 7, 6, 1, 7, 1, 5, 8, 4];

var indexTable = {}, uniqueValues = [];

// --- build reverse index table, find unique values

for(var i = foo.length; i--; ) {
    var value = foo[i];
    if(indexTable.hasOwnProperty(value))
        indexTable[value].push(i);
    else {
        indexTable[value] = [i];
        uniqueValues.push(value);
    }
}

// --- sort unique values in ascending order

uniqueValues.sort(function(i1, i2) {
    return i1 - i2;
});

// --- find ten greatest values

var fooTopTen = [], k = 0;

for(var i = uniqueValues.length; k < 10 && i--; ) {
    var value = uniqueValues[i],
        indices = indexTable[value];

    for(var j = indices.length; k < 10 && j--; )
        fooTopTen[k++] = [indices[j], value];
}

// --- output result

document.writeln('[[' + fooTopTen.join('], [') + ']]');
var foo=[2,2,4,4,128,2,2,1,4,128,2,2,1,18,21,5,1,128,1,2,2,2,1,18,12,60,2,28,1,17,2,3,4,2,2,2,1,27,2,17,2,2,2,5,1,2,4,7,1,2,1,1,2,1,1,5,2,7,8,4];
var indexTable={},uniqueValues=[];
//---构建反向索引表,查找唯一值
for(var i=foo.length;i--;){
var值=foo[i];
if(indexTable.hasOwnProperty(value))
可索引[值]。推送(i);
否则{
可索引[值]=[i];
uniqueValues.push(值);
}
}
//---按升序对唯一值进行排序
uniqueValues.sort(函数(i1,i2){
返回i1-i2;
});
//---找出十大价值观
var fooTopTen=[],k=0;
对于(var i=uniqueValues.length;k<10&&i--;){
var值=唯一值[i],
指数=可索引[值];
对于(var j=index.length;k<10&&j--;)
fooTopTen[k++]=[指数[j],值];
}
//---输出结果
document.writeln('['+fooTopTen.join('],[')+']]);

我以前的回答使用了反向索引表,但包含一些错误-现在已经修复-比下面的代码更难理解

这实际上是答案中给出的所有解决方案中速度最慢的一个——为了获得最佳性能,请查看我的其他答案

var foo = [2, 2, 4, 4, 128, 2, 2, 1, 4, 18, 27, 16, 2, 1, 18, 21, 5, 1, 128, 1, 2, 2, 1, 18, 12, 60, 2, 28, 1, 17, 2, 3, 4, 2, 2, 2, 1, 27, 2, 17, 7, 2, 2, 2, 5, 1, 2, 4, 7, 1, 2, 1, 1, 1, 2, 1, 5, 7, 2, 7, 6, 1, 7, 1, 5, 8, 4];

var fooTopTen = [];

// add index to values
for(var i = 0, len = foo.length; i < len; ++i)
    fooTopTen.push([i, foo[i]]);

// sort first by value (descending order), then by index (ascending order)
fooTopTen.sort(function(t1, t2) {
    return t2[1] - t1[1] || t1[0] - t2[0];
});

// shorten array to correct size
fooTopTen.length = 10;

// output top ten to check result
document.writeln('[[' + fooTopTen.join('], [') + ']]');
var foo=[2,2,4,4,128,2,2,1,4,128,2,2,1,18,21,5,1,128,1,2,2,2,1,18,12,60,2,28,1,17,2,3,4,2,2,2,1,27,2,17,2,2,2,5,1,2,4,7,1,2,1,1,2,1,1,5,2,7,8,4];
var fooTopTen=[];
//向值添加索引
对于(变量i=0,len=foo.length;i

比较函数的第二部分(比较索引的部分)不需要,因为在大多数实现中,
sort()
是稳定的(ECMA不需要)。我将把它作为一个例子,说明如何根据多个需求进行排序…

我以前的回答使用了反向索引表,但包含一些错误,这些错误现在已经修复,并且比下面的代码更难理解

var foo = [2, 2, 4, 4, 128, 2, 2, 1, 4, 18, 27, 16, 2, 1, 18, 21, 5, 1, 128, 1, 2, 2, 1, 18, 12, 60, 2, 28, 1, 17, 2, 3, 4, 2, 2, 2, 1, 27, 2, 17, 7, 2, 2, 2, 5, 1, 2, 4, 7, 1, 2, 1, 1, 1, 2, 1, 5, 7, 2, 7, 6, 1, 7, 1, 5, 8, 4];

var index = 0;
var result = foo.map( function(a){ return [index++, a]; } )
         .sort( function(a,b){ return (a[1] < b[1]); } )
         .splice( 0, 10 );

document.write(result.join( '  ' ));
这实际上是答案中给出的所有解决方案中速度最慢的一个——为了获得最佳性能,请查看我的其他答案

var foo = [2, 2, 4, 4, 128, 2, 2, 1, 4, 18, 27, 16, 2, 1, 18, 21, 5, 1, 128, 1, 2, 2, 1, 18, 12, 60, 2, 28, 1, 17, 2, 3, 4, 2, 2, 2, 1, 27, 2, 17, 7, 2, 2, 2, 5, 1, 2, 4, 7, 1, 2, 1, 1, 1, 2, 1, 5, 7, 2, 7, 6, 1, 7, 1, 5, 8, 4];

var fooTopTen = [];

// add index to values
for(var i = 0, len = foo.length; i < len; ++i)
    fooTopTen.push([i, foo[i]]);

// sort first by value (descending order), then by index (ascending order)
fooTopTen.sort(function(t1, t2) {
    return t2[1] - t1[1] || t1[0] - t2[0];
});

// shorten array to correct size
fooTopTen.length = 10;

// output top ten to check result
document.writeln('[[' + fooTopTen.join('], [') + ']]');
var foo=[2,2,4,4,128,2,2,1,4,128,2,2,1,18,21,5,1,128,1,2,2,2,1,18,12,60,2,28,1,17,2,3,4,2,2,2,1,27,2,17,2,2,2,5,1,2,4,7,1,2,1,1,2,1,1,5,2,7,8,4];
var fooTopTen=[];
//向值添加索引
对于(变量i=0,len=foo.length;i
比较函数的第二部分(比较索引的部分)不需要,因为在大多数实现中,
sort()
是稳定的(ECMA不需要)。我将把它作为一个例子,说明如何根据多个需求进行排序…

var foo=[2,2,4,128,2,2,1,4,18,27,16,2,1,18,21,5,1,128,1,2,2,2,1,18,12,60,2,28,1,17,3,4,2,2,1,27,2,2,5,1,2,1,1,1,2,2,2,1,2,2,1,2,2,2,2,7,7,8,5];
var foo = [2, 2, 4, 4, 128, 2, 2, 1, 4, 18, 27, 16, 2, 1, 18, 21, 5, 1, 128, 1, 2, 2, 1, 18, 12, 60, 2, 28, 1, 17, 2, 3, 4, 2, 2, 2, 1, 27, 2, 17, 7, 2, 2, 2, 5, 1, 2, 4, 7, 1, 2, 1, 1, 1, 2, 1, 5, 7, 2, 7, 6, 1, 7, 1, 5, 8, 4];

var index = 0;
var result = foo.map( function(a){ return [index++, a]; } )
         .sort( function(a,b){ return (a[1] < b[1]); } )
         .splice( 0, 10 );

document.write(result.join( '  ' ));
var指数=0; var result=foo.map(函数(a){return[index++,a];}) .sort(函数(a,b){返回(a[1]
如果与所需结果的大小相比,foo非常大,那么当我们遇到它时,迭代foo插入将每个元素排序到结果中可能会更快。

var foo=[2,2,4,4,128,2,2,1,4,18,27,16,2,1,18,21,5,1,128,1,2,2,1,
// Sorting method
function sortNumber(a, b) {
    return a - b;
}

// Find the offset of an element in array
function findOffset(element, array) {
    for (var i = 0; i < array.length; i++) {
        if (array[i] == element) {
            // Make sure we don't find it again
            array[i] = null;
            return i;
        }
    }
}

var foo = [2, 2, 4, 4, 128, 2, 2, 1, 4, 18, 27, 16, 2, 1, 18, 21, 5, 1, 128, 1, 2, 2, 1, 18, 12, 60, 2, 28, 1, 17, 2, 3, 4, 2, 2, 2, 1, 27, 2, 17, 7, 2, 2, 2, 5, 1, 2, 4, 7, 1, 2, 1, 1, 1, 2, 1, 5, 7, 2, 7, 6, 1, 7, 1, 5, 8, 4];
// Copies
var bar = foo.slice();
var baz = foo.slice();
var fooTopTen = new Array(10);
// Sort
bar.sort(sortNumber).reverse();
// Create the results
for (var i = 0; i < 10; i++) {
    fooTopTen[i] = new Array(2);
    fooTopTen[i][0] = findOffset(bar[i], baz);
    fooTopTen[i][1] = bar[i];
}