使用es2015重新排列动态数组

时间:2017-05-30 10:37:05

标签: javascript arrays sorting

我正在使用页面中的一些数据来操作和重新排序数组。到目前为止,我已根据一个serperate“排序数组”顺序重新排序了我的对象数组。原始阵列是这样的:

[  
   {  
      "domain":"www.exampleurl.com/redirect",
      "retailerName":"eBay",
      "providerName":"ebay",
      "needProcessing":false
   },
   {  
      "domain":"www.exampleurl.com/redirect",
      "retailerName":"Cheap-Coilovers.co.uk",
      "providerName":"pricerunner",
      "needProcessing":false
   },
   {  
      "domain":"www.exampleurl.com/redirect",
      "retailerName":"House of Fraser",
      "providerName":"connexity",
      "needProcessing":false
   },
   {  
      "domain":"www.exampleurl.com/redirect",
      "retailerName":"notonthehighstreet.com",
      "providerName":"connexity",
      "needProcessing":false
   }
]

然后我通过我的sort函数运行这个数组:

function compare(a, b) {
    let sortingArr = ['connexity', 'ecn', 'kelkoo', 'nexttag', 'pricerunner', 'shopping', 'ebay'];

    if (sortingArr.indexOf(a.providerName) < sortingArr.indexOf(b.providerName)) {
       return -1;
    }
    if (sortingArr.indexOf(a.providerName) > sortingArr.indexOf(b.providerName)) { 
       return 1;
    }
  return 0;
}
retailersOrdered.sort(compare);

然后按照排序数组的顺序给出了我的对象数组,它很棒,并且具有所需的效果:

[  
   {  
      "domain":"www.exampleurl.com/redirect",
      "retailerName":"House of Fraser",
      "providerName":"connexity",
      "needProcessing":false
   },
   {  
      "domain":"www.exampleurl.com/redirect",
      "retailerName":"notonthehighstreet.com",
      "providerName":"connexity",
      "needProcessing":false
   },
   {  
      "domain":"www.exampleurl.com/redirect",
      "retailerName":"Cheap-Coilovers.co.uk",
      "providerName":"pricerunner",
      "needProcessing":false
   },
   {  
      "domain":"www.exampleurl.com/redirect",
      "retailerName":"eBay",
      "providerName":"ebay",
      "needProcessing":false
   }
]

我现在想更进一步,以一种“循环”的方式命令阵列。因此,第一个对象使用providerName“connexity”,然后第一个对象使用providerName“pricerunner”,然后第一个对象使用providerName“ebay”然后回到开头,第二个对象使用providerName“connexity”,依此类推。给出所需的输出:

[  
   {  
      "domain":"www.exampleurl.com/redirect",
      "retailerName":"House of Fraser",
      "providerName":"connexity",
      "needProcessing":false
   },
   {  
      "domain":"www.exampleurl.com/redirect",
      "retailerName":"Cheap-Coilovers.co.uk",
      "providerName":"pricerunner",
      "needProcessing":false
   },
   {  
      "domain":"www.exampleurl.com/redirect",
      "retailerName":"eBay",
      "providerName":"ebay",
      "needProcessing":false
   },
   {  
      "domain":"www.exampleurl.com/redirect",
      "retailerName":"notonthehighstreet.com",
      "providerName":"connexity",
      "needProcessing":false
   }
]

此数组是动态构建的,每个提供程序具有不同数量的对象。我努力想出一种按提供者[1]的顺序排序这个数组的方法,然后是动态名称和长度的提供者[2]。我希望有一些es2015的新功能可以帮助实现这一目标吗?任何以这种方式排序数组的知识都会很棒。

1 个答案:

答案 0 :(得分:0)

这个想法是一次将一个元素拼接在一起,直到所有元素都按循环顺序添加。这可以通过创建正在使用的providerNames的有序列表,按providerName对项目进行分组,然后将正确的元素推送到要返回的新数组来实现。这是一个演示:

var data = [  
   {  
      "domain":"www.exampleurl.com/redirect",
      "retailerName":"eBay",
      "providerName":"ebay",
      "needProcessing":false
   },
   {  
      "domain":"www.exampleurl.com/redirect",
      "retailerName":"Cheap-Coilovers.co.uk",
      "providerName":"pricerunner",
      "needProcessing":false
   },
   {  
      "domain":"www.exampleurl.com/redirect",
      "retailerName":"House of Fraser",
      "providerName":"connexity",
      "needProcessing":false
   },
   {  
      "domain":"www.exampleurl.com/redirect",
      "retailerName":"notonthehighstreet.com",
      "providerName":"connexity",
      "needProcessing":false
   }
];

var providerNameIndex = 0;
// group objects by provider name
var groupedByProviderName = data.reduce(function (result, current) {
    if (!result[current.providerName]) {
        result[current.providerName] = [];
    }
    result[current.providerName].push(current);
    return result;
}, {});

// get providerNames in use, sorted in order specified by sortingArr
var providerNames = Object.keys(groupedByProviderName).sort(function (a, b) {
    let sortingArr = ['connexity', 'ecn', 'kelkoo', 'nexttag', 'pricerunner', 'shopping', 'ebay'];
    if (sortingArr.indexOf(a) < sortingArr.indexOf(b)) {
      return -1;
    }
    if (sortingArr.indexOf(a) > sortingArr.indexOf(b)) { 
      return 1;
    }
  return 0;
});

function stitch (obj) {
    var results = [];
    // repeat until all items have been placed in new array
    while(providerNames.some(name => obj[name].length)) {
        // cycle through provider names
        var providerName = providerNames[providerNameIndex % providerNames.length];
        // if array still has items, push first item into new arr
        if(obj[providerName].length) {
            results.push(obj[providerName].shift());
        }
        // increment index to get next provider name in sequence
        providerNameIndex++;
    }
    
    return results;
}

console.log(stitch(groupedByProviderName));