6

我有一个大小如下的数组:

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'

  ...
];

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

4

6 回答 6

6

只需为您的排序方法定义一个记分器。这是你的代码。尝试一下

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

工作小提琴

于 2013-03-21T05:42:05.263 回答
1

此答案仅适用于您描述的确切情况,即数组的长度是 5 的偶数倍,并且值按小、中和大分类,每个小和中的数量是大的两倍。

它可能适用于任何排序的值数组 where 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
于 2013-03-21T06:14:12.350 回答
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

于 2013-03-21T07:14:59.813 回答
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;
于 2013-03-21T05:50:45.457 回答
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]);
    }
}
于 2013-03-21T05:57:09.433 回答
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'));

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

希望有帮助!

于 2013-04-06T09:36:32.603 回答