Как использовать Array.prototype.filter для выборочной фильтрации данных Json при переименовании свойств объекта в результирующем массиве?

У меня есть Json, который выглядит следующим образом

{
    "score": "1200.65",
    "num_games": "160",
    "wins": "110",
    "year": "2013"
},
{
    "score": "705.23",
    "num_games": "34",
    "wins": "21",
    "year": "2014"
},
{
    "score": "467.12",
    "num_games": "77",
    "wins": "30",
    "year": "2015"
},

Я хотел бы создать массив объектов (содержащих x и y), которые могут быть отфильтрованы по диапазону лет (например, годы между 2014 и 2015) для свойства x и значения конкретного свойства как y (например, «оценка»). Например, если я отфильтрую по диапазону 2014-2015 годов и по свойству "Score", результирующий массив должен быть:

[{x:'2014', y: 705.23}, {x:'2015', y: 467.12}]

Другой пример, если я отфильтрую по диапазону 2014-2015 и по Свойство "num_games", результирующий массив должен быть:

[{x:'2014', y: 34}, {x:'2015', y: 77}]

Как мне идти об этом? Является ли Array.prototype.filter правильным инструментом для этого?

0
задан Tom 18 March 2019 в 13:18
поделиться

4 ответа

Фильтр, Карта, Уничтожение объектов могут выполнять работу:

const y = [{
    "score": "1200.65",
    "num_games": "160",
    "wins": "110",
    "year": "2013"
  },
  {
    "score": "705.23",
    "num_games": "34",
    "wins": "21",
    "year": "2014"
  },
  {
    "score": "467.12",
    "num_games": "77",
    "wins": "30",
    "year": "2015"
  }
];


const res = y.filter(o => o.year == 2014).map(({
  year: x,
  score: y
}) => ({
  x,
  y
}))

console.log(res)

0
ответ дан G.aziz 18 March 2019 в 13:18
поделиться
  1. Фильтрация массива с помощью Array#filter
  2. Преобразование элементов массива в тип по вашему выбору с использованием Array#map

var data = [{"score": "1200.65", "num_games": "160", "wins": "110", "year": "2013" }, { "score": "705.23", "num_games": "34", "wins": "21", "year": "2014" }, { "score": "467.12", "num_games": "77", "wins": "30", "year": "2015" }];

function getFilteredData(data, start, end) {
  return data.filter(function(item) {
    return +start <= +item.year && +item.year <= +end;
  }).map(function(item) {
    return {
      x: item.year,
      y: item.score
    };
  });
}

console.log(getFilteredData(data, 2014, 2017));

Если ваши даты находятся в разумных пределах, вам не нужно конвертировать год в number, но любые 3–5-значные годы не будут фильтроваться должным образом, если вы не конвертируете годы в числа.

Если вы хотите более абстрактную версию функции, вы можете сделать:

var data = [{"score": "1200.65", "num_games": "160", "wins": "110", "year": "2013" }, { "score": "705.23", "num_games": "34", "wins": "21", "year": "2014" }, { "score": "467.12", "num_games": "77", "wins": "30", "year": "2015" }];

function getFilteredData(data, filterOptions, mapOptions) {
  return data.filter(function(item) {
    return Object.keys(filterOptions).every(function(key) {
      var option = filterOptions[key];
      if (+option.min <= +item[key] && +item[key] <= +option.max) return true;
    });
  }).map(function(item) {
    return Object.keys(mapOptions).reduce(function(result, key) {
      var option = mapOptions[key];
      result[key] = item[option];
      return result;
    }, {});
  });
}

function registerFilter(filterOptions, mapOptions) {
  return function(data) {
    return getFilteredData(data, filterOptions, mapOptions);
  };
}

var customFilter = registerFilter(
  { year: { min: 2014, max: 2015 },
  { x: "year", y: "score" }
);

console.log(customFilter(data));

Вы можете сделать обе операции вместе используя петлю for или Array#reduce. Что делает код более быстрым, но менее обслуживаемым.

var data = [{"score": "1200.65", "num_games": "160", "wins": "110", "year": "2013" }, { "score": "705.23", "num_games": "34", "wins": "21", "year": "2014" }, { "score": "467.12", "num_games": "77", "wins": "30", "year": "2015" }];

function getFilteredData(data, start, end) {
  return data.reduce(function(result, item) {
    if (+start <= +item.year && +item.year <= +end) result.push({
      x: item.year,
      y: item.score
    });
    return result;
  }, []);
}

console.log(getFilteredData(data, 2014, 2017));

0
ответ дан nick zoum 18 March 2019 в 13:18
поделиться

Сначала отфильтруйте массив по датам, затем сопоставьте отфильтрованные элементы с требуемым форматом. Вы можете использовать деструктуризацию, чтобы сделать код короче:

const data = [{
    "score": "1200.65",
    "num_games": "160",
    "wins": "110",
    "year": "2013"
}, {
    "score": "705.23",
    "num_games": "34",
    "wins": "21",
    "year": "2014"
}, {
    "score": "467.12",
    "num_games": "77",
    "wins": "30",
    "year": "2015"
}];

const filterBy = (data, [min, max], prop) => data
  .filter(({ year }) => year >= min && year <= max)
  .map(({ year: x, [prop]: y }) => ({ x, y }));

console.log(filterBy(data, [2013, 2014], 'score'));
console.log(filterBy(data, [2013, 2013], 'wins'));

0
ответ дан jo_va 18 March 2019 в 13:18
поделиться

Вы можете использовать .filter , чтобы получить объекты в требуемом диапазоне, а затем использовать .map для создания объектов из отфильтрованного списка.

См. Пример ниже:

const arr = [{
    "score": "1200.65",
    "num_games": "160",
    "wins": "110",
    "year": "2013"
},
{
    "score": "705.23",
    "num_games": "34",
    "wins": "21",
    "year": "2014"
},
{
    "score": "467.12",
    "num_games": "77",
    "wins": "30",
    "year": "2015"
}];

const get_items = (arr, [sY, eY], prop) => 
   arr
    .filter(({year}) => +sY <= year && year <= +eY)
    .map(({year:x, ...rest}) => ({x, y: rest[prop]}));


console.log(get_items(arr, ["2014", "2015"], "score"));

0
ответ дан Nick Parsons 18 March 2019 в 13:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: