根据键值对的匹配集循环遍历对象数组并过滤/排序/分组。

时间:2018-05-24 12:01:08

标签: javascript arrays reactjs sorting ecmascript-6

我有一些这样的数据:

"players": [
    {
    "name": "Molla Wague",
    "position": "Centre-Back",
    "jerseyNumber": 13,
    "dateOfBirth": "1991-02-21",
    "nationality": "Mali",
    "contractUntil": "2018-06-30",
    "marketValue": null
    },
    {
    "name": "Heurelho Gomes",
    "position": "Keeper",
    "jerseyNumber": 1,
    "dateOfBirth": "1981-02-15",
    "nationality": "Brazil",
    "contractUntil": "2019-06-30",
    "marketValue": null
    },
    {
    "name": "Christian Kabasele",
    "position": "Centre-Back",
    "jerseyNumber": 27,
    "dateOfBirth": "1991-02-24",
    "nationality": "Belgium",
    "contractUntil": "2021-06-30",
    "marketValue": null
    },
    {
    "name": "José Holebas",
    "position": "Left-Back",
    "jerseyNumber": 25,
    "dateOfBirth": "1984-06-27",
    "nationality": "Greece",
    "contractUntil": "2020-06-30",
    "marketValue": null
    },
    {
    "name": "Daryl Janmaat",
    "position": "Right-Back",
    "jerseyNumber": 2,
    "dateOfBirth": "1989-07-22",
    "nationality": "Netherlands",
    "contractUntil": "2020-06-30",
    "marketValue": null
    },
    {
    "name": "Étienne Capoue",
    "position": "Defensive Midfield",
    "jerseyNumber": 29,
    "dateOfBirth": "1988-07-11",
    "nationality": "France",
    "contractUntil": "2019-06-30",
    "marketValue": null
    },
    {
    "name": "Tom Cleverley",
    "position": "Central Midfield",
    "jerseyNumber": 8,
    "dateOfBirth": "1989-08-12",
    "nationality": "England",
    "contractUntil": "2022-06-30",
    "marketValue": null
    },
    {
    "name": "Roberto Pereyra",
    "position": "Attacking Midfield",
    "jerseyNumber": 37,
    "dateOfBirth": "1991-01-07",
    "nationality": "Argentina",
    "contractUntil": "2021-06-30",
    "marketValue": null
    },
    {
    "name": "Troy Deeney",
    "position": "Centre-Forward",
    "jerseyNumber": 9,
    "dateOfBirth": "1988-06-29",
    "nationality": "England",
    "contractUntil": "2021-06-30",
    "marketValue": null
    }
]

有些玩家有不同的职位

我想按照他们的位置命令每个球员,所以所有守门员先到先得,然后是所有中后卫,依此类推。

我正在使用React和Redux。我在Reducer文件中完成了一些工作,但我认为代码过于臃肿,下面是一个例子:

function sortPlayersByPosition(data) {
  let players = data.players;
  let result = [];

    result.push(players.filter(function(obj) {
      return obj.position === 'Keeper';
    }));

    result.push(players.filter(function(obj) {
      return obj.position === 'Centre-Back';
    }));

    result.push(players.filter(function(obj) {
      return obj.position === 'Right-Back';
    }));

    result.push(players.filter(function(obj) {
      return obj.position === 'Left-Back';
    }));

    result.push(players.filter(function(obj) {
      return obj.position === 'Defensive Midfield';
    }));

    result.push(players.filter(function(obj) {
      return obj.position === 'Central Midfield';
    }));

    result.push(players.filter(function(obj) {
      return obj.position === 'Attacking Midfield';
    }));

    result.push(players.filter(function(obj) {
      return obj.position === 'Right Wing';
    }));

    result.push(players.filter(function(obj) {
      return obj.position === 'Left Wing';
    }));

    result.push(players.filter(function(obj) {
      return obj.position === 'Centre-Forward';
    }));

    data.players = result;

    return data
}

export const fetchTeamPlayersReducer = (state = [], action) => {
  switch (action.type) {
    case 'FETCH_TEAM_PLAYERS_SUCCESS':

        var sortedPlayers = sortPlayersByPosition(action.payload);
      return sortedPlayers;
    default:
      return state;
  }
}

Click here to see output of the code above

所以你可以看到我把我的位置分成了不同的数组。我不希望这个结果。如果我有一个包含对象的数组,我真的很喜欢它。就像原始格式一样。

欢迎任何帮助。

谢谢!

3 个答案:

答案 0 :(得分:1)

您可以先制作有序位置数组:

const ORDERS = [
  'Keeper',
  'Centre-Back',
  ...
]

这个ORDERS数组的初始数组的排序

players.sort((player1, player2) => {
  return ORDERS.indexOf(player2.position) - ORDERS.indexOf(player1.position);
});

答案 1 :(得分:0)

您可以尝试:

a = module.myvar
b = module.myfunc(a)

输出:

const positions = [
  'Keeper', 'Centre-Back', 'Right-Back', 'Left-Back', 'Defensive Midfield',
  'Central Midfield', 'Attacking Midfield', 'Right Wing', 'Left Wing', 'Centre-Forward',
];

data.players.sort((a, b) => positions.indexOf(a.position) > positions.indexOf(b.position));

答案 2 :(得分:0)

您可以定义包含排序优先级的对象,并定义自定义排序功能,如下所示:

players = [
    {
    "name": "Molla Wague",
    "position": "Centre-Back",
    "jerseyNumber": 13,
    "dateOfBirth": "1991-02-21",
    "nationality": "Mali",
    "contractUntil": "2018-06-30",
    "marketValue": null
    },
    {
    "name": "Heurelho Gomes",
    "position": "Keeper",
    "jerseyNumber": 1,
    "dateOfBirth": "1981-02-15",
    "nationality": "Brazil",
    "contractUntil": "2019-06-30",
    "marketValue": null
    },
    {
    "name": "Christian Kabasele",
    "position": "Centre-Back",
    "jerseyNumber": 27,
    "dateOfBirth": "1991-02-24",
    "nationality": "Belgium",
    "contractUntil": "2021-06-30",
    "marketValue": null
    },
    {
    "name": "José Holebas",
    "position": "Left-Back",
    "jerseyNumber": 25,
    "dateOfBirth": "1984-06-27",
    "nationality": "Greece",
    "contractUntil": "2020-06-30",
    "marketValue": null
    },
    {
    "name": "Daryl Janmaat",
    "position": "Right-Back",
    "jerseyNumber": 2,
    "dateOfBirth": "1989-07-22",
    "nationality": "Netherlands",
    "contractUntil": "2020-06-30",
    "marketValue": null
    },
    {
    "name": "Étienne Capoue",
    "position": "Defensive Midfield",
    "jerseyNumber": 29,
    "dateOfBirth": "1988-07-11",
    "nationality": "France",
    "contractUntil": "2019-06-30",
    "marketValue": null
    },
    {
    "name": "Tom Cleverley",
    "position": "Central Midfield",
    "jerseyNumber": 8,
    "dateOfBirth": "1989-08-12",
    "nationality": "England",
    "contractUntil": "2022-06-30",
    "marketValue": null
    },
    {
    "name": "Roberto Pereyra",
    "position": "Attacking Midfield",
    "jerseyNumber": 37,
    "dateOfBirth": "1991-01-07",
    "nationality": "Argentina",
    "contractUntil": "2021-06-30",
    "marketValue": null
    },
    {
    "name": "Troy Deeney",
    "position": "Centre-Forward",
    "jerseyNumber": 9,
    "dateOfBirth": "1988-06-29",
    "nationality": "England",
    "contractUntil": "2021-06-30",
    "marketValue": null
    }
];

sortOrder = {
	"Keeper": 0,
	"Centre-Back": 1,
	"Centre-Forward": 2,
	"Left-Back": 3,
	"Right-Back": 4,
	"Defensive Midfield": 5,
	"Central Midfield": 6,
	"Attacking Midfield": 7,

};

function sort(player1, player2) {
	const player1Value = sortOrder[player1.position];
	const player2Value = sortOrder[player2.position];
	if(player1Value > player2Value) { return 1; }
	else if (player1Value < player2Value) { return -1; }
	else { return 0; }
}

console.log(players.sort(sort));