这是进一步扩展previous question.的尝试。我觉得这完全不同,可以提出另一个主题,希望能帮助尝试解决同一问题的任何人。
如果我有一个键-值对的数据集,那么我要完成三件事:
查找内部键值对的值的第一个匹配项。
将该值复制到地图中
将另一个键值对的值用作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"}
]
我想结束以下Map对象:
[
"2019-01-01" => "snow",
"2019-02-01" => "none",
"2019-03-01" => "rain",
"2019-06-01" => "hail"
]
作为最后的挑战,如何在可以动态生成结果的函数中执行此操作?因此,在上面的示例中,我在最终Map中选择了“ precip”作为所需值。但是,如果我想要“季节”怎么办?有没有一种方法可以动态地做到这一点,在这里我可以将“键”名作为函数的参数传递?
另外,此操作是否有名称?我很难拿到头衔。如果有人有更好的主意,我很乐意将其重命名。我觉得这是很多人都可能遇到的一个优雅的问题。
最佳答案
您可以使用Array#filter
删除所有最终会产生重复值的条目Array#map
在您的数据上生成键值对
只是collect into a Map via the constructor
要使其具有动态性,您只需要提供用于键和值的属性名称即可:
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}`);
}
请注意,这使用了
.filter
的第二个参数-它设置了回调的this
上下文。通过将其设置为Set,可以确保仅用于.filter
操作-您无需在整个函数范围内保留额外的变量。另外,由于它设置了this
上下文,因此您需要普通的function
而不是箭头功能,因为this
的值不能更改。关于javascript - 将Javascript数组简化为Map,从内部值创建键,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57292700/