【问题标题】:How to use Array.prototype.filter to selectively filter Json data while renaming object's properties in the resulting array?如何使用 Array.prototype.filter 在重命名结果数组中对象的属性时选择性地过滤 Json 数据?
【发布时间】:2019-08-08 21:03:14
【问题描述】:

我有一个像这样的 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 属性创建一个对象数组(包含 x 和 y),这些对象可以按年份范围(例如 2014 年到 2015 年之间的年份)过滤,并将特定属性的值作为 y (例如“分数”)。 例如,如果我按 2014-2015 年的范围和属性“分数”进行过滤,则结果数组应为:

[{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 是正确的工具吗?

【问题讨论】:

  • 首先filter您要选择的对象,然后map将它们转换为所需格式的新对象(带有xy属性)。

标签: javascript array.prototype.map


【解决方案1】:
  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));

【讨论】:

    【解决方案2】:

    首先按日期过滤数组,然后将过滤后的项目映射到您需要的格式。您可以使用解构来使代码更短:

    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'));

    【讨论】:

      【解决方案3】:

      您可以使用.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"));

      【讨论】:

        【解决方案4】:

        您可以过滤和映射想要的值。

        function getParts(array, [min, max], key) {
            return array
                .filter(({ year }) => +min <= year && year <= +max)
                .map(({ year: x, [key]: y }) => ({ x, y }));
        }
        
        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" }];
        
        console.log(getParts(data, [2014, 2015], 'score'));
        console.log(getParts(data, [2014, 2015], 'num_games'));
        .as-console-wrapper { max-height: 100% !important; top: 0; }

        【讨论】:

          【解决方案5】:

          Filter , Map , Object Destructing 可以胜任:

          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)

          【讨论】:

            猜你喜欢
            • 2020-06-02
            • 2019-01-03
            • 2021-04-15
            • 2016-05-15
            • 1970-01-01
            相关资源
            最近更新 更多