重新排列数组javascript中的对象

时间:2017-04-05 12:13:04

标签: javascript arrays ecmascript-6

我有一个从API返回的对象数组。

let arr = [
  {name: 'Blur'},
  {name: 'The Beatles'},
  {name: 'Oasis'},
  {name: 'Arctic Monkeys'},
  {name: 'Elvis'}
];

我总是希望Arctic MonkeysOasis之前来一个,并保留其他项目。有时API会以正确的顺序返回它们,但在某些情况下,它们会像上面那样错误。

有人可以建议最好的方法吗?

我知道我可以做这样的事情,但觉得必须有更好的方法。

for(let i = 0; i < arr.length; i++){
  if(arr[i].name == 'Arctic Monkeys' && arr[i - 1].name === 'Oasis' ){
    let oasisObj = arr[i];
    arr[i - 1] = arr[i];
    arr[i] = oasisObj;
  }
}

或许我不应该改变这个数组并创建一个全新的数组?

4 个答案:

答案 0 :(得分:1)

"/_GET"

答案 1 :(得分:1)

这是一个带有数组的函数,以及该数组中两个项目的名称。然后确保第一个命名项目直接出现在第二个命名项目之前!

var ensureAbove = function(arr, above, below) {
    // Find the indices of the above and below items
    var aboveInd = -1;
    var belowInd = -1;
    for (var i = 0; i < arr.length; i++) {
         if (arr[i].name === above) aboveInd = i;
         if (arr[i].name === below) belowInd = i;

         // If we've found both indices we can stop looking
         if (aboveInd > -1 && belowInd > -1) break;
    }

    // Now ensure that the item at index `aboveInd` comes before
    // index `belowInd`
    var loInd = Math.min(belowInd, aboveInd);
    var hiInd = Math.max(belowInd, aboveInd);

    // All the items before `aboveInd` and `belowInd`
    var itemsBefore = arr.slice(0, loInd);

    // All the items after both `aboveInd` and `belowInd`
    var itemsAfter = arr.slice(hiInd + 1);

    // All the items between `aboveInd` and `belowInd`
    var itemsBetween = arr.slice(loInd + 1, hiInd);

    /*
    Ok here's the tactical bit. We can definitely add all the
    `itemsBefore` as the very first thing, and we can definitely
    add all the `itemsAfter` as the very last thing. This middle
    is trickier - we either want to add the above and below items and then
    the middle items, OR we add the middle items first and then the above or
    below items.
    */

    var result = itemsBefore;

    if (belowInd < aboveInd) {
        result.push(arr[aboveInd]);
        result.push(arr[belowInd]);
    }

    result = result.concat(itemsBetween);

    if (belowInd > aboveInd) {
        result.push(arr[aboveInd]);
        result.push(arr[belowInd]);
    }

    result = result.concat(itemsAfter);

    return result;
};

现在将此代码应用于您的数组:

let arr = [
    {name: 'Blur'},
    {name: 'The Beatles'},
    {name: 'Oasis'},
    {name: 'Arctic Monkeys'},
    {name: 'Elvis'}
];
let orderedArr = ensureAbove(arr, 'Arctic Monkeys', 'Oasis');

请注意,根据您的具体情况,修复API可能会更有效。

答案 2 :(得分:0)

我认为最好的方法是在服务器端使用一些特定的排序规则进行调整。要在客户端上修复特定方案,您可能会这样做。

let arr = [
  {name: 'Blur'},
  {name: 'The Beatles'},
  {name: 'Oasis'},
  {name: 'Arctic Monkeys'},
  {name: 'Elvis'}
]

console.log(arr.map(o => o.name))

let iO = arr.findIndex(o => o.name === 'Oasis')
let iA = arr.findIndex(o => o.name === 'Arctic Monkeys')

if ((iA !== -1 && iO !== -1) && iA > iO) {
  let o = arr[iO]
  let a = arr[iA]
  arr[iO] = a
  arr[iA] = o
}

console.log(arr.map(o => o.name))

答案 3 :(得分:0)

您可以使用对象并检查两个名称是否都在对象中。

Array#sort可能无法产生稳定的结果,具体取决于实施的排序算法。

let arr = [{ name: 'Blur' }, { name: 'The Beatles' }, { name: 'Oasis' }, { name: 'Arctic Monkeys' }, { name: 'Elvis' }],
order = { 'Arctic Monkeys': 1, Oasis: 2 };

arr.sort((a, b) => (b.name in order) && (a.name in order) ? order[a.name] - order[b.name] : 0);

console.log(arr);
.as-console-wrapper { max-height: 100% !important; top: 0; }