【问题标题】:javascript sort sparse array keep indexesjavascript排序稀疏数组保持索引
【发布时间】:2012-08-27 07:16:13
【问题描述】:

对稀疏数组进行排序并使元素保持在相同索引上的最佳方法是什么? 例如:

a[0] = 3, 
a[1] = 2, 
a[2] = 6,
a[7] = 4,
a[8] = 5,

我想在排序后有

a[0] = 2, 
a[1] = 3, 
a[2] = 4, 
a[7] = 5, 
a[8] = 6.

【问题讨论】:

  • 如果我能很好地理解您的问题,也许您可​​以尝试使用以下关键词进行谷歌搜索:“排序”、“关联数组”、“按值”。

标签: javascript sorting sparse-array


【解决方案1】:

这是一种方法。它将定义的数组元素复制到一个新数组并保存它们的索引。它对新数组进行排序,然后将排序结果放回之前使用的索引中。

var a = [];
a[0] = 3;
a[1] = 2; 
a[2] = 6; 
a[7] = 4; 
a[8] = 5;


// sortFn is optional array sort callback function, 
// defaults to numeric sort if not passed
function sortSparseArray(arr, sortFn) {
    var tempArr = [], indexes = [];
    for (var i = 0; i < arr.length; i++) {
        // find all array elements that are not undefined
        if (arr[i] !== undefined) {
            tempArr.push(arr[i]);    // save value
            indexes.push(i);         // save index
        }
    }
    // sort values (numeric sort by default)
    if (!sortFn) {
        sortFn = function(a,b) {
            return(a - b);
        }
    }
    tempArr.sort(sortFn);
    // put sorted values back into the indexes in the original array that were used
    for (var i = 0; i < indexes.length; i++) {
        arr[indexes[i]] = tempArr[i];
    }
    return(arr);
}

工作演示:http://jsfiddle.net/jfriend00/3ank4/

【讨论】:

  • @jfriend000,如果我直接用.sort()呢?
  • 而且@jfriend00 从未想过编写“符合堆栈排序”的代码会给他带来如此多的支持和积分;)
  • @OrhanC1 - 我修好了。该代码正在执行字典排序(因此它适用于字符串条目)。现在,它被设置为数字排序。
  • 由于 stacksort 的强大支持 :)
  • 接下来:@jfriend00 变得流氓并将代码更改为完全恶意。数百名 xkcd 读者受到影响。
【解决方案2】:

你可以

  1. 使用filterObject.values 获取包含稀疏数组值的数组。
  2. 然后sort 那个数组,从大到小。请注意,它不稳定,如果某些值不是数字,这可能会特别成问题。您可以使用自己的排序实现。
  3. 使用mappop 获得所需的数组。将其分配给a
var b = a.filter(function(x) {
    return true;
}).sort(function(x,y) {
    return y - x;
});
a = a.map([].pop, b);

或者,在 ECMAScript 2017 中,

a = a.map([].pop, Object.values(a).sort((x,y) => y-x));

【讨论】:

  • 变量b在ES5代码中是不需要的,但是我用它来让代码更具可读性。
  • 作为奖励,如果将 map 返回分配给新变量,则原始 a 不会被修改。干得好,奥里奥尔。我讨厌 [].sort 默认发生变异。
  • 如果我们可以假设稀疏数组中的所有元素都是数字的(如果没有这个假设,排序回调的行为会不一致!),那么我们可以只使用a.filter(() =&gt; true)Object.values(a) 过滤元素。
  • @GOTO0 谢谢,可能我忘了filter 使用 HasProperty 跳过不存在的属性。
【解决方案3】:
var arr = [1,2,3,4,5,6,7,8,9,10];
// functions sort
function sIncrease(i, ii) { // ascending
 if (i > ii)
 return 1;
 else if (i < ii)
 return -1;
 else
 return 0;
}
function sDecrease(i, ii) { //descending
 if (i > ii)
 return -1;
 else if (i < ii)
 return 1;
 else
 return 0;
}
function sRand() { // random
 return Math.random() > 0.5 ? 1 : -1;
}
arr.sort(sIncrease); // return [1,2,3,4,5,6,7,8,9,10]
arr.sort(sDecrease); // return [10,9,8,7,6,5,4,3,2,1]
arr.sort(sRand); // return random array for examle [1,10,3,4,8,6,9,2,7,5]

【讨论】:

  • 我认为这不是问题真正要问的。
【解决方案4】:
// Update for your needs ('position' to your key).

function updateIndexes( list ) {

    list.sort( ( a, b ) => a.position - b.position )

    list.forEach( ( _, index, arr ) => {

        arr[ index ].position = index

    } )

}

var myList = [
   { position: 8 },
   { position: 5 },
   { position: 1 },
   { position: 9 }
]

updateIndexes( myList )

// Result:

var myList = [
   { position: 1 },
   { position: 2 },
   { position: 3 },
   { position: 4 }
]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-14
    • 2015-06-18
    • 2021-03-12
    • 1970-01-01
    • 2019-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多