根据对象的字符串属性之一对数组中的对象重新排序?

时间:2019-09-14 22:32:18

标签: javascript

当前,我从API GET请求中接收到包含3个对象的数组,但是我想根据其属性之一对对象进行重新排序。

例如,我希望属性为queueType: "RANKED_SOLO_5x5"的对象成为数组中的第一个元素,而属性为queueType: "RANKED_TFT"的第二个对象成为第二个元素,并且如果有两个以上的对象,任何顺序都适合其余的它们,我只希望前两个元素是具有属性queueType: "RANKED_SOLO_5x5"queueType: "RANKED_TFT"

的元素

可以做到吗?

这是我从1位用户的API中获得的对象:

[
  {
    "rank": "IV",
    "tier": "PLATINUM",
    "wins": 17,
    "losses": 116,
    "veteran": false,
    "inactive": false,
    "leagueId": "e62390f0-aad4-11e9-9332-c81f66dd0e0d",
    "hotStreak": false,
    "queueType": "RANKED_TFT",
    "freshBlood": false,
    "summonerId": "TUCyI-h1s6ZJBNiag9c9ZBIkFxBCeP6Yn7i8GpHeuhYPI-Y",
    "leaguePoints": 23,
    "summonerName": "The Onyx King"
  },
  {
    "rank": "IV",
    "tier": "PLATINUM",
    "wins": 312,
    "losses": 318,
    "veteran": true,
    "inactive": false,
    "leagueId": "000d4c70-767a-11e9-9acb-c81f66dacb22",
    "hotStreak": false,
    "queueType": "RANKED_SOLO_5x5",
    "freshBlood": false,
    "summonerId": "TUCyI-h1s6ZJBNiag9c9ZBIkFxBCeP6Yn7i8GpHeuhYPI-Y",
    "leaguePoints": 0,
    "summonerName": "The Onyx King"
  }
]

这是我在另一个物体上得到的物体:

[
  {
    "rank": "II",
    "tier": "GOLD",
    "wins": 634,
    "losses": 694,
    "veteran": true,
    "inactive": false,
    "leagueId": "af7c0330-99f8-11e9-a190-c81f66db01ef",
    "hotStreak": false,
    "queueType": "RANKED_SOLO_5x5",
    "freshBlood": false,
    "summonerId": "z7n0ZG97hF5_wbOvDRwv2dk05STsdRO2ed4thi7dKl7yEfA",
    "leaguePoints": 53,
    "summonerName": "Chazmie"
  },
  {
    "rank": "II",
    "tier": "SILVER",
    "wins": 51,
    "losses": 64,
    "veteran": false,
    "inactive": false,
    "leagueId": "bd777110-b530-11e9-92ba-c81f66dacb22",
    "hotStreak": false,
    "queueType": "RANKED_FLEX_SR",
    "freshBlood": false,
    "summonerId": "z7n0ZG97hF5_wbOvDRwv2dk05STsdRO2ed4thi7dKl7yEfA",
    "leaguePoints": 12,
    "summonerName": "Chazmie"
  },
  {
    "rank": "IV",
    "tier": "SILVER",
    "wins": 5,
    "losses": 36,
    "veteran": false,
    "inactive": false,
    "leagueId": "6b7f3610-acc3-11e9-9ce9-c81f66db01ef",
    "hotStreak": false,
    "queueType": "RANKED_TFT",
    "freshBlood": true,
    "summonerId": "z7n0ZG97hF5_wbOvDRwv2dk05STsdRO2ed4thi7dKl7yEfA",
    "leaguePoints": 11,
    "summonerName": "Chazmie"
  }
]

如您所见,对象的数量可以变化,但是我只对在数组的开头拥有queueType:“ RANKED_SOLO_5x5”和queueType:“ RANKED_TFT”的对象感兴趣,我不在乎顺序第三和以后。

1 个答案:

答案 0 :(得分:1)

我要使用的算法是:

  1. 找到符合条件的元素的索引
  2. 删除对象并将其保存在找到的索引中
  3. 在数组开头的正确索引处插入对象

我应该注意,如果存在重复项,则由于在索引0或1处插入了重复项,因此该顺序可能会在数组的开头变得混乱;

const dataArray = [
  {
    id: 56734567,
    queueType: "RANKED_SOLO_1x1",
  },
  {
    id: 293402,
    queueType: "RANKED_SOLO_1x1",
  },
  {
    id: 85643,
    queueType: "RANKED_TFT",
  },
  {
    id: 446457,
    queueType: "RANKED_SOLO_1x1",
  },
  {
    id: 456235,
    queueType: "RANKED_SOLO_1x1",
  },
  {
    id: 678657,
    queueType: "RANKED_SOLO_1x1",
  },
  {
    id: 42342,
    queueType: "RANKED_SOLO_5x5",
  },
  {
    id: 13465346,
    queueType: "RANKED_SOLO_1x1",
  },
  {
    id: 334632,
    queueType: "RANKED_SOLO_1x1",
  },
];

const key0 = "RANKED_SOLO_5x5";
const key1 = "RANKED_TFT";

const sortOrder = [
  key0, // sort key0 to index 0
  key1, // sort key1 to index 1
];

const sortData = (array = [], sortStartOrder = []) => {
  // Higher order find function to take key to search for
  const findByQueueType = key => ({ queueType }) => queueType === key;
  
  // Higher order forEach function to find by key, remove and insert at new index
  const findAndChangeOrder = array => (key, newIndex) => {
    const objectIndex = array.findIndex(findByQueueType(key)); // (1) find index
    if (objectIndex !== -1) {
      const object = array.splice(objectIndex, 1).shift(); // (2) remove object at index if found
      object && array.splice(newIndex, 0, object); // (3) insert at desired index
    }
  };
  
  const newArray = [...array]; // copy in to not mutate passed array

  // For each sortStartOrder entry, use value as search key and index as newIndex
  sortStartOrder.forEach(findAndChangeOrder(newArray));
  
  return newArray;
};

const sortedArray = sortData(dataArray, sortOrder);

console.log(sortedArray);