将Javascript数组简化为Map,从内部值创建键

jas*_*ose 1 javascript arrays reduce object key-value

这是试图进一步解决先前的问题。。我觉得这完全不同,可以提出另一个主题,希望能帮助尝试解决同一问题的任何人。

如果我有一个键-值对的数据集,那么我要完成三件事:

  1. 查找内部键值对的值的第一个匹配项。
  2. 将该值复制到地图中
  3. 将另一个键值对的值用作Map的键。

因此,举例来说,我有以下数据集:

[
  {"date":"2019-01-01", "temp":"cold", "season":"winter", "precip":"snow"},
  {"date":"2019-02-01", "temp":"cold", "season":"winter", "precip":"none"},
  {"date":"2019-03-01", "temp":"mild", "season":"spring", "precip":"rain"},
  {"date":"2019-04-01", "temp":"mild", "season":"spring", "precip":"none"},
  {"date":"2019-05-01", "temp":"warm", "season":"spring", "precip":"rain"},
  {"date":"2019-06-01", "temp":"warm", "season":"summer", "precip":"hail"},
  {"date":"2019-07-01", "temp":"hot", "season":"summer", "precip":"none"}
]
Run Code Online (Sandbox Code Playgroud)

我想结束以下Map对象:

[
  "2019-01-01" => "snow",
  "2019-02-01" => "none",
  "2019-03-01" => "rain",
  "2019-06-01" => "hail"
]
Run Code Online (Sandbox Code Playgroud)

作为最后的挑战,如何在可以动态生成结果的函数中执行此操作?因此,在上面的示例中,我在最终Map中选择了“ precip”作为所需值。但是,如果我想要“季节”怎么办?有没有一种方法可以动态地做到这一点,在这里我可以将“键”名作为函数的参数传递?

另外,此操作是否有名称?我很难拿到头衔。如果有人有更好的主意,我很乐意将其重命名。我觉得这是很多人都可能遇到的一个优雅的问题。

VLA*_*LAZ 6

您可以使用

  1. Array#filter 删除将最终产生重复值的所有条目
  2. Array#map 在您的数据上产生键值对
  3. 只需通过构造函数收集到Map中

要使其具有动态性,您只需要提供用于键和值的属性名称即可:

const data = [
  {"date":"2019-01-01", "temp":"cold", "season":"winter", "precip":"snow"},
  {"date":"2019-02-01", "temp":"cold", "season":"winter", "precip":"none"},
  {"date":"2019-03-01", "temp":"mild", "season":"spring", "precip":"rain"},
  {"date":"2019-04-01", "temp":"mild", "season":"spring", "precip":"none"},
  {"date":"2019-05-01", "temp":"warm", "season":"spring", "precip":"rain"},
  {"date":"2019-06-01", "temp":"warm", "season":"summer", "precip":"hail"},
  {"date":"2019-07-01", "temp":"hot", "season":"summer", "precip":"none"}
];

function transform(keyProp, valueProp, arr) {
  const keyValuePairs = arr
    .filter(function(obj) {
      const value = obj[valueProp];
      //only keep the value if it hasn't been encountered before
      const keep = !this.has(value);

      //add the value, so future repeats are removed
      this.add(value)

      return keep;
    }, new Set()) // <-- pass a Set to use as `this` in the callback
    .map(obj => [obj[keyProp], obj[valueProp]]);
  
  return new Map(keyValuePairs);
}

const map = transform("date", "precip", data);

//Stack Snippets don't print the Map content
//via console.log(map), so doing it manually
for (let [key, value] of map) {
  console.log(`${key} -> ${value}`);
}
Run Code Online (Sandbox Code Playgroud)

请注意,这将第二个参数用于.filter-设置this回调的上下文。通过将其设置为Set,可以确保仅将其用于.filter操作-您无需在整个函数的范围内保留额外的变量。另外,由于它设置了this上下文,因此您需要一个法线function而不是箭头函数,因为箭头this值不能更改。