Фильтруйте массив объектов, сохраняя объекты с соответствующим ключом, а также смежные объекты - PullRequest
0 голосов
/ 03 сентября 2018

Мне было трудно сформулировать заголовок, чтобы описать проблему, с которой я столкнулся, однако я надеюсь, что пример будет полезен. У меня есть массив объектов JavaScript, который выглядит примерно так:

const myPlayer = "jim"
const myArray = 
    [
      {"player":"bob", "points":11},
      {"player":"joe", "points":15},
      {"player":"nik", "points":18},
      {"player":"tom", "points":21},
      {"player":"jim", "points":25},
      {"player":"ron", "points":26},
      {"player":"tim", "points":32},
      {"player":"jon", "points":35},
      {"player":"len", "points":42},
      {"player":"eva", "points":51}
    ];

Мой массив сортирует объекты по ключу points , и я хотел бы отфильтровать этот массив, чтобы сохранить (a) объект, ключ которого player совпадает с myPlayer переменная, а также (b) 2 объекта до и 2 объекта после объекта, который соответствует переменной myPlayer . Например, в этом случае я хотел бы вернуть следующее:

const filtArray = 
    [
      {"player":"nik", "points":18},
      {"player":"tom", "points":21},
      {"player":"jim", "points":25},
      {"player":"ron", "points":26},
      {"player":"tim", "points":32}
    ];

... поскольку nik и tom - это два объекта до jim, а ron и tim - два объекта после tim. Клавиша player будет иметь уникальное значение для каждого объекта, поэтому никогда не будет двух объектов с одинаковой клавишей player .

Последняя часть этого вопроса - я бы хотел, чтобы отфильтрованный массив всегда содержал 5 объектов. Поэтому, если myPlayer = "bob", где bob является игроком в самом первом объекте, я бы хотел, чтобы он просто возвращал первые 5 объектов, например:

 [
  {"player":"bob", "points":11},
  {"player":"joe", "points":15},
  {"player":"nik", "points":18},
  {"player":"tom", "points":21},
  {"player":"jim", "points":25}
];

... с похожим выводом, если myPlayer = "joe" или myPlayer = "len" или "eva".

Любая помощь с этим приветствуется, спасибо !!

Edit: похоже, у меня просто была небольшая ошибка в моем коде, которая нарушала мой подход ... есть следующее, которое использует findIndex и slice:

const index = myArray.findIndex(x => x.player === myPlayer);    
filtArray = myArray.slice(index-2, index+2)

Ответы [ 3 ]

0 голосов
/ 03 сентября 2018

Вы можете сделать это, найдя индекс игрока, которого вы ищете, а затем перебрав массив и создав новый список игроков с индексом в этом диапазоне.

const myPlayer = "jim"
const myArray = [
    {"player":"bob", "points":11},
    {"player":"joe", "points":15},
    {"player":"nik", "points":18},
    {"player":"tom", "points":21},
    {"player":"jim", "points":25},
    {"player":"ron", "points":26},
    {"player":"tim", "points":32},
    {"player":"jon", "points":35},
    {"player":"len", "points":42},
    {"player":"eva", "points":51}
]

function indexOfPlayer(arr, player) {
    return arr.map(i => i.player).indexOf(player)
}

function getItemWithSurrounding(arr, index, around) {
    result = []
    for (i = index - around; i <= index + around; i++) {
        if (i >= 0 && i < arr.length) {
            result.push(arr[i])
        }
    }
    return result
}
playerIndex = indexOfPlayer(myArray, myPlayer)
players = getItemWithSurrounding(myArray, playerIndex, 2)
console.log(players)

Выход:

[
  {
    "player": "nik",
    "points": 18
  },
  {
    "player": "tom",
    "points": 21
  },
  {
    "player": "jim",
    "points": 25
  },
  {
    "player": "ron",
    "points": 26
  },
  {
    "player": "tim",
    "points": 32
  }
]
0 голосов
/ 03 сентября 2018

Вы можете использовать метод Array.findIndex, чтобы найти правильного игрока в массиве, затем использовать Array.slice с парой операторов if, чтобы выбрать правильный сегмент массива (либо первые 5, если первый или второй игрок последние 5, если выбран один из двух последних игроков, или пять, окружающих «внутреннего» игрока).

const myPlayer = "jim"
const myArray = 
    [
      {"player":"bob", "points":11},
      {"player":"joe", "points":15},
      {"player":"nik", "points":18},
      {"player":"tom", "points":21},
      {"player":"jim", "points":25},
      {"player":"ron", "points":26},
      {"player":"tim", "points":32},
      {"player":"jon", "points":35},
      {"player":"len", "points":42},
      {"player":"eva", "points":51}
    ];

function filterArray(array, playerName) {
  let idx = array.findIndex(o => o.player === playerName)
  if (array.length - idx <= 2) {
    return array.slice(array.length - 5)
  } else if (idx < 2) {
    return array.slice(0, 5)
  } else {
    return array.slice(idx - 2, idx + 3)
  }
}

console.log(filterArray(myArray, myPlayer)) // "jim" is an "inner" player, so the surrounding elements are returned
console.log(filterArray(myArray, "joe")) // "joe" is an "outer" player, so the first five elements are returned
console.log(filterArray(myArray, "eva")) // "eva" is an "outer" player, so the last five elements are returned
0 голосов
/ 03 сентября 2018

Вы можете сделать один for loop для первой части и slice() для второй, но, как вы сказали, если вы выберете eva, отобразятся первые 5, если вы хотите что-то другое, вы можете изменить только срез.

const myPlayer = "ron";
const myArray = [
  { player: "bob", points: 11 },
  { player: "joe", points: 15 },
  { player: "nik", points: 18 },
  { player: "tom", points: 21 },
  { player: "jim", points: 25 },
  { player: "ron", points: 26 },
  { player: "tim", points: 32 },
  { player: "jon", points: 35 },
  { player: "len", points: 42 },
  { player: "eva", points: 51 }
];

var newArray = [];

for (let i = 0; i < myArray.length; i++) {
  if (myArray[i].player == myPlayer){
      var index = i;//<-- store the index to probably be used in slice
    if ((i-2)>=0 && (i+2)<myArray.length) {
    newArray.push(myArray[i - 2]);
    newArray.push(myArray[i - 1]);
    newArray.push(myArray[i]);
    newArray.push(myArray[i + 1]);
    newArray.push(myArray[i + 2]);
  }
}
}

if(newArray.length == 0){
    newArray = myArray.slice(0, 6) 
}

console.log(newArray);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...