将Javascript数组缩减为映射,从内部值创建键

将Javascript数组缩减为映射,从内部值创建键,javascript,arrays,object,key-value,reduce,Javascript,Arrays,Object,Key Value,Reduce,这是一种进一步的尝试。我觉得这是完全不同的,足以保证另一个主题,希望能帮助任何试图解决相同问题的人 如果我有一个键值对数据集,假设我想完成3件事: 查找内部键值对的值的第一个匹配项 将该值复制到映射中 使用另一个键值对的值作为映射的键 例如,假设我有以下数据集: [ {"date":"2019-01-01", "temp":"cold", "season":"winter", "precip":"snow"}, {"date":"2019-02-01", "temp":"cold", "

这是一种进一步的尝试。我觉得这是完全不同的,足以保证另一个主题,希望能帮助任何试图解决相同问题的人

如果我有一个键值对数据集,假设我想完成3件事:

  • 查找内部键值对的值的第一个匹配项
  • 将该值复制到映射中
  • 使用另一个键值对的值作为映射的键
  • 例如,假设我有以下数据集:

    [
      {"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"}
    ]
    
    我希望以以下贴图对象结束:

    [
      "2019-01-01" => "snow",
      "2019-02-01" => "none",
      "2019-03-01" => "rain",
      "2019-06-01" => "hail"
    ]
    
    最后一个挑战是,在一个结果可以是动态的函数中,我如何做到这一点?因此,在上面的示例中,我在最终地图中选择了“precip”作为所需的值。但如果我想要“季节”呢?有没有一种方法可以动态地这样做,我可以将“key”名称作为函数的参数传递

    还有,这个操作有名字吗?我很难想出一个标题。如果有人有更好的主意,我很乐意给它改名。我觉得这是一个优雅的问题,许多人可能会遇到。

    你可以使用

  • 删除最终将产生重复值的任何条目
  • 覆盖数据以生成键值对
  • 只是
  • 要获得这种动态特性,只需提供用于键和值的属性名称:

    const数据=[
    {“日期”:“2019-01-01”,“温度”:“寒冷”,“季节”:“冬季”,“降水”:“雪”},
    {“日期”:“2019-02-01”,“温度”:“寒冷”,“季节”:“冬季”,“降水”:“无”},
    {“日期”:“2019-03-01”,“温度”:“温和”,“季节”:“春季”,“降水”:“雨水”},
    {“日期”:“2019-04-01”,“温度”:“温和”,“季节”:“春季”,“精度”:“无”},
    {“日期”:“2019-05-01”,“温度”:“温暖”,“季节”:“春天”,“降水”:“雨水”},
    {“日期”:“2019-06-01”,“温度”:“温暖”,“季节”:“夏季”,“降水”:“冰雹”},
    {“日期”:“2019-07-01”,“温度”:“炎热”,“季节”:“夏季”,“降水”:“无”}
    ];
    函数转换(keyProp、valueProp、arr){
    常量keyValuePairs=arr
    .过滤器(功能(obj){
    常量值=对象[valueProp];
    //仅当以前未遇到该值时才保留该值
    const keep=!this.has(值);
    //添加该值,以便删除将来的重复
    这个。增加(价值)
    返回保持;
    },new Set())//[obj[keyProp],obj[valueProp]];
    返回新映射(keyValuePairs);
    }
    常量映射=转换(“日期”、“精度”、数据);
    //堆栈代码段不会打印地图内容
    //通过console.log(map)执行,因此手动执行
    for(让[键,值]映射){
    log(`${key}->${value}`);
    }
    您可以使用

  • 删除最终将产生重复值的任何条目
  • 覆盖数据以生成键值对
  • 只是
  • 要获得这种动态特性,只需提供用于键和值的属性名称:

    const数据=[
    {“日期”:“2019-01-01”,“温度”:“寒冷”,“季节”:“冬季”,“降水”:“雪”},
    {“日期”:“2019-02-01”,“温度”:“寒冷”,“季节”:“冬季”,“降水”:“无”},
    {“日期”:“2019-03-01”,“温度”:“温和”,“季节”:“春季”,“降水”:“雨水”},
    {“日期”:“2019-04-01”,“温度”:“温和”,“季节”:“春季”,“精度”:“无”},
    {“日期”:“2019-05-01”,“温度”:“温暖”,“季节”:“春天”,“降水”:“雨水”},
    {“日期”:“2019-06-01”,“温度”:“温暖”,“季节”:“夏季”,“降水”:“冰雹”},
    {“日期”:“2019-07-01”,“温度”:“炎热”,“季节”:“夏季”,“降水”:“无”}
    ];
    函数转换(keyProp、valueProp、arr){
    常量keyValuePairs=arr
    .过滤器(功能(obj){
    常量值=对象[valueProp];
    //仅当以前未遇到该值时才保留该值
    const keep=!this.has(值);
    //添加该值,以便删除将来的重复
    这个。增加(价值)
    返回保持;
    },new Set())//[obj[keyProp],obj[valueProp]];
    返回新映射(keyValuePairs);
    }
    常量映射=转换(“日期”、“精度”、数据);
    //堆栈代码段不会打印地图内容
    //通过console.log(map)执行,因此手动执行
    for(让[键,值]映射){
    log(`${key}->${value}`);
    
    }
    这是一个很好的场景,适用于
    Array.prototype.reduce

    const invertMap=map=>{
    const entires=Array.from(map.entries());
    const reversedKeyValues=entires.map(([key,value])=>[value,key]);
    返回新映射(reversedKeyValues);
    };
    常数天气记录=[
    {“日期”:“2019-01-01”,“温度”:“寒冷”,“季节”:“冬季”,“降水”:“雪”},
    {“日期”:“2019-02-01”,“温度”:“寒冷”,“季节”:“冬季”,“降水”:“无”},
    {“日期”:“2019-03-01”,“温度”:“温和”,“季节”:“春季”,“降水”:“雨水”},
    {“日期”:“2019-04-01”,“温度”:“温和”,“季节”:“春季”,“精度”:“无”},
    {“日期”:“2019-05-01”,“温度”:“温暖”,“季节”:“春天”,“降水”:“雨水”},
    {“日期”:“2019-06-01”,“温度”:“温暖”,“季节”:“夏季”,“降水”:“冰雹”},
    {“日期”:“2019-07-01”,“温度”:“炎热”,“季节”:“夏季”,“降水”:“无”}
    ];
    const firstPrecipToDate=天气记录。reduce((acc,log)=>{
    const{date,precip}=log;
    如果(!acc.has(precip)){
    //只有在我们还没有precip->date`地图的情况下才能将precip添加到地图中
    acc.set(精度、日期);
    }
    返回acc;
    },新地图());
    //现在将地图反转为日期->精度
    const datetopreip=invertMap(firstPrecipToDate);
    控制台日志(dateToPrecip);
    
    log('--在stackoverflow中显示为空对象,查看浏览器控制台')这是
    数组.prototype.reduce的一个很好的场景

    const invertMap=map=>{
    const entires=Array.from(map.entries());
    const reversedKeyValues=entires.map(([key,value])=>[value,key]);
    返回新映射(reversedKeyValues);
    };
    常数天气记录=[
    {“日期”:“2019-01-01”,“温度”:“寒冷”,“季节”:“冬季”,“降水”:“雪”},
    {“日期”:“2019-02-01”,“温度”:“寒冷”,“季节”:“冬季”,“降水”:“无”},
    {“日期”:“2019-03-01”,“温度”:“温和”,“季节”:“春季”,“降水”:“雨水”},
    {“日期”:“2019-04-01”,“tem”
    
    const arr = [{"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"}];
    
    const key = "precip";
    
    const res = new Map(Object.entries(arr.reduceRight((a, { date, [key]: c }) => (a[c] = date, a), {})).map(e => e.reverse()).sort(([a], [b]) => new Date(a) - new Date(b)));
    
    console.log(res);
    
    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 getFirstOccurenceMap(key, value) {
        const myMap = new Map();
        for (let i=0; i<data.length; i++) {
            if (data[i][value] && !myMap.has(data[i][value])) {
                myMap.set(data[i][value], data[i][key]);
            }
        }
        result = new Map();
        if (myMap) {
            for (var [key, value] of myMap) {
                if (!result.has(value)) {
                    result.set(value, key);
                }
            }
        }
        return result;
    }
    
    console.log(getFirstOccurenceMap("date", "temp"));