#javascript #node.js #arrays #compare #put
Вопрос:
Я исполняю два GET requests
. Один в мою базу данных, а другой из API.
У меня есть два массива объектов. В массиве из моей базы данных он будет содержать данные игроков с некоторыми из их «Активных» статусов, установленных в true
или false
(я создаю функцию на переднем конце своего приложения, которая позволяет пользователю контролировать, активен ли кто-то или нет). В массиве из API он также будет содержать данные игроков, но ВСЕ их «Активные» статусы установлены true
по умолчанию, и эти данные извлекаются каждые 24 часа и отправляются в мою базу данных через a PUT request
и перезаписывают все данные.
Цель: Если для статуса «Активный» в массиве из базы данных установлено значение false, я хочу игнорировать эти объекты в массиве из API и обновлять базу данных только 'Active': true
игроками.
Вот пример того, что было бы в моей базе данных:
[{
"PlayerID": 12345,
"Team": "ABC",
"FirstName": "Patrick",
"LastName": "Star",
"Position": "RB",
"Active": false,
"__v": 0
},
{
"PlayerID": 67890,
"Team": "DEF",
"FirstName": "Spongebob",
"LastName": "Squarepants",
"Position": "WR",
"Active": true,
"__v": 0
}]
Вот пример из API. Обратите внимание, что «Активный» статус Патрика Стара соответствует действительности:
[{
"PlayerID": 12345,
"Team": "ABC",
"FirstName": "Patrick",
"LastName": "Star",
"Position": "RB",
"Active": true,
"__v": 0
},
{
"PlayerID": 67890,
"Team": "DEF",
"FirstName": "Spongebob",
"LastName": "Squarepants",
"Position": "WR",
"Active": true,
"__v": 0
}]
Я хочу сравнить эти два массива и вернуть новый массив с активными игроками (в данном случае Губка Боб Квадратные штаны). Таким образом, игроки 'Active': false
, которые находятся, не затрагиваются в базе данных. Я подумал, что могу использовать «Идентификатор игрока» в качестве ссылки, чтобы помочь определить, какие игроки активны или нет, и отфильтровать их оттуда. Но я застрял — любая помощь приветствуется!
РЕДАКТИРОВАТЬ — Вот моя функция, которая должна быть реализована в:
function getPlayers() {
const APIplayersURL = "someURL";
const DBoffensivePlayersURL = "http://localhost:4000/api/offensiveplayers";
axios.get(DBoffensivePlayersURL).then((res) => {
const inactivePlayers = res.data;
// Filter out all of the active players
const dbArr = inactivePlayers.filter(
players =>
players.Active === false
);
axios.get(APIplayersURL).then((res) => {
const players = res.data;
// Filter out all players except for QB, RB and WR
const offensivePlayers = players.filter(
players =>
players.Position === "QB" ||
players.Position === "RB" ||
players.Position === "WR"
);
// Give me all active QBs, RBs, and WRs
const apiArr = offensivePlayers.filter(
offensivePlayers =>
offensivePlayers.Status === "Active"
);
const result = dbArr.filter(
(obj) => obj.Active amp;amp; apiArr.some((o) => o.PlayerID === obj.PlayerID)
);
console.log(result);
const config = {
headers: {
"Content-Type": "application/json",
"Authorization": "x-auth-token",
"Access-Control-Allow-Origin": "*"
},
};
axios
.put("http://localhost:4000/api/offensiveplayers", result, config)
.then((res) => console.log(res))
.catch((err) => console.error(err));
console.log("Players updated successfully");
});
});
}
// Runs the getPlayers every 24 hours
setInterval(getPlayers, 86400000);
Ответ №1:
Вы можете использовать фильтр здесь, чтобы отфильтровать объекты, которые существуют apiArr
, и один и тот же объект со PlayerID
Active
статусом true
dbArr.filter((obj) => obj.Active amp;amp; apiArr.some((o) => o.PlayerID === obj.PlayerID));
const dbArr = [
{
PlayerID: 12345,
Team: "ABC",
FirstName: "Patrick",
LastName: "Star",
Position: "RB",
Active: false,
__v: 0,
},
{
PlayerID: 67890,
Team: "DEF",
FirstName: "Spongebob",
LastName: "Squarepants",
Position: "WR",
Active: true,
__v: 0,
},
];
const apiArr = [
{
PlayerID: 12345,
Team: "ABC",
FirstName: "Patrick",
LastName: "Star",
Position: "RB",
Active: true,
__v: 0,
},
{
PlayerID: 67890,
Team: "DEF",
FirstName: "Spongebob",
LastName: "Squarepants",
Position: "WR",
Active: true,
__v: 0,
},
];
const result = dbArr.filter(
(obj) => obj.Active amp;amp; apiArr.some((o) => o.PlayerID === obj.PlayerID)
);
console.log(result);
Комментарии:
1. Вы могли бы ускорить выполнение, воспользовавшись коротким замыканием в состоянии фильтра, так как нет причин делать
.some
, еслиobj.Active
значение false.2. Мне это и в голову не приходило. Это прекрасная часть оптимизации. Спасибо за предложение @StevenB.
3. @decpk Огромное спасибо за ответ! Поэтому я внедрил это в свой код, но он возвращает пустой массив :/ Я отредактировал свой вопрос, чтобы включить свою функцию. Возможно, вы видите, чего мне не хватает.
Ответ №2:
Используйте метод фильтра для удаления объектов/значений, которые не возвращают значение true.
const players = [{
PlayerID: 12345,
Team: "ABC",
FirstName: "Patrick",
LastName: "Star",
Position: "RB",
Active: false,
__v: 0
},
{
PlayerID: 67890,
Team: "DEF",
FirstName: "Spongebob",
LastName: "Squarepants",
Position: "WR",
Active: true,
__v: 0
}];
const online = players.filter(player => player?.Active);
console.log(online);
Теперь, если вы хотите, чтобы ignore
пользователи, которые находятся в автономном режиме в БД, вы также можете использовать идентификатор для проверки.
const playersDB = [{
PlayerID: 12345,
Team: "ABC",
FirstName: "Patrick",
LastName: "Star",
Position: "RB",
Active: false,
__v: 0
},
{
PlayerID: 67890,
Team: "DEF",
FirstName: "Spongebob",
LastName: "Squarepants",
Position: "WR",
Active: true,
__v: 0
}
];
const playersAPI = [{
PlayerID: 12345,
Team: "ABC",
FirstName: "Patrick",
LastName: "Star",
Position: "RB",
Active: true,
__v: 0
},
{
PlayerID: 67890,
Team: "DEF",
FirstName: "Spongebob",
LastName: "Squarepants",
Position: "WR",
Active: true,
__v: 0
}
];
const online = playersAPI.filter(player => {
const copy = playersDB.filter(p => p.PlayerID == player.PlayerID);
if(!copy.length) return false;
return copy[0].Active;
})
console.log(online)
Комментарии:
1. Это будет фильтровать только объекты , чей
Active
статус естьtrue
, но вы не проверяете, существует ли он также в массиве, который исходит изAPI