根据另一个Array的顺序对Array进行排序

时间:2013-03-21 05:31:47

标签: javascript sorting

我有一个像这样大小的数组:

var arr = [
  'small',
  'small',
  'small',
  'small',
  ...
  'medium',
  'medium',
  'medium',
  'medium',
  ...
  'big',
  'big',
  ...
];

我需要按照这个顺序重新组织这个数组:

var order = ['small', 'small', 'medium', 'medium', 'big'];

所以结果最终会是这样的:

var arr = [
  'small',
  'small',
  'medium',
  'medium',
  'big',

  'small',
  'small',
  'medium',
  'medium',
  'big'

  ...
];

我知道其他类似的问题,但到目前为止我找不到任何东西。我不确定如何处理这个问题。我在想sort应该做什么,但我要测试什么?看起来很简单,但我卡住了,不知道从哪里开始。任何提示?

6 个答案:

答案 0 :(得分:3)

只需为您的排序方法定义一个得分手。 这是你的代码。试试吧

var init_arr = ['small', 'big', 'big', 'medium'];

var scorer = {
   small: 0,
   medium: 1,
   big: 2
}

// You can use the same array too. I am creating new one.
var final_arr = init_arr.sort(function(a,b) {
   return scorer[a]-scorer[b];
});

alert(final_arr); //small, medium, big, big

Working Fiddle

答案 1 :(得分:1)

这个答案仅适用于您所描述的确切情况,即数组的长度是5的偶数倍,值分为小,中,大三种,每种中小型的数量是其中的两倍很大。

它可能适用于length % 5 == 0的任何排序值数组,但结果可能不是您想要的结果:

function reOrder(array) {
  var result = [];
  var f = array.length/5; // this must be an integer
  var t;

  for (var i=0; i<f; i++) {
    t = i*2;
    result.push.call(result, array.slice(t, t+2));
    t = f*2 + i*2;
    result.push.call(result, array.slice(t, t+2));
    t = f*4 + i;
    result.push.call(result, array.slice(t, t+1));
  }
  return result; 
} 

var a = ['s','s','s','s','s','s','m','m','m','m','m','m','b','b','b'];
alert(reOrder(a)); // s,s,m,m,b,s,s,m,m,b,s,s,m,m,b

答案 2 :(得分:1)

好吧,我最终得到了这个有效的解决方案:

function orderBy(arr, order) {
  var result = [],
      i = 0, len = arr.length,
      index;

  while (result.length < len) {
    index = arr.indexOf(order[i]);
    result.push(arr[index]);
    arr.splice(index, 1);
    i = i >= order.length-1 ? 0 : ++i;
  }

  return result;
}

它修改了原始数组,但没关系。

演示:http://jsbin.com/umizat/1/edit

答案 3 :(得分:0)

为什么不创建3个数组并根据大小拆分数据,然后就可以按给定的顺序检索数据。

等;

SMALL[];
MEDIUM[];
BIG[];

for(i,j,k : upto array lengths : i++,j++,k++){

   nwArray.add(SMALL[i]);
   nwArray.add(SMALL[++i]);
   nwArray.add(MEDIUM[j]);
   nwArray.add(MEDIUM[++j]);
   nwArray.add(BIG[k]);

}

return newArray;

答案 4 :(得分:0)

我的方法是循环遍历order数组并拉出元素,直到数组为空或没有所需的元素。

var sorted = [];
var arr = [
  'small',
  'small',
  'small',
  'small',
  ...
  'medium',
  'medium',
  'medium',
  'medium',
  ...
  'big',
  'big',
  ...
];
var order = ['small', 'small', 'medium', 'medium', 'big'];

out:
while (true) {
  for (var i = 0; i < order.length; i++) {
    var index = arr.indexOf(order[i]);
    if ((index === -1) or (arr.length === 0)) {
      break out;
    } else {
      var elem = arr.splice(index, 1);
      sorted.append(elem[0]);
    }
}

答案 5 :(得分:0)

我知道这个问题已经过时了,你有一个目前正在使用的答案,但是我想提供这个例子和JSFiddle以获得一个解决方案,该解决方案可以用于任何类型的修改以结束。

注意原始数组中遗留的任何内容都会添加到新数组的末尾,并且不会被排除。如果数组中没有足够的项目来填充order的要求,则会从订单中跳过缺少的元素。

现在,到函数:

function mySort(arr, order) {
    var newAr = [];
    var orIndex = 0;
    while(arr.length != 0) {
        var type = order[orIndex];
        var ind = arr.indexOf(type);
        if(ind != -1) {
            newAr.push(type);
            arr.splice(ind, 1);
        }
        orIndex++;
        if(orIndex >= order.length) {
            orIndex = 0;
        }
    }
    return newAr;
}

这样做,是否需要您的示例数组:

var arrTest = [
  'small',
  'small',
  'small',
  'small',
  'small',
  'small',
  'small',
  'small',
  'medium',
  'medium',
  'medium',
  'medium',
  'medium',
  'medium',
  'medium',
  'medium',
  'big',
  'big',
  'big',
  'big',
];
var orderTest = ['small', 'small', 'medium', 'medium', 'big'];

现在,您可以根据需要更改这些内容,但它会对它们进行文本搜索,因此如果您希望对其进行排序,请确保它在完整数组和顺序数组中都相同。现在,要使用该功能,您可以:

var sortedArray = mySort(arrTest, orderTest);

或者,我如何在小提琴演示:

alert(mySort(arrTest, orderTest).join('\n'));

这应该适用于涉及两者的任何情况,并且可以轻松修改订单。

希望有所帮助!