用第一个键值替换NaN值

时间:2018-12-06 15:39:21

标签: javascript json

我有这个对象

{
  "apple": {
    "0": {
      "2018-04-25 19:51:38": {
        "x": "38.0",
        "y": "23.0"
      },
      "2018-04-25 19:51:39": {
        "x": "NaN",
        "y": "NaN"
      },
      "2018-04-25 19:51:40": {
        "x": "NaN",
        "y": "NaN"
      }
    },
    "5": {
      "2018-04-25 19:51:38": {
        "x": "50.0",
        "y": "35.0"
      },
      "2018-04-25 19:51:39": {
        "x": "50.0",
        "y": "35.0"
      },
      "2018-04-25 19:51:40": {
        "x": "NaN",
        "y": "NaN"
      },
      "2018-04-25 19:51:41": {
        "x": "NaN",
        "y": "NaN"
      },
    },
    "6": {
      "2018-04-25 19:51:34": {
        "x": "30.0",
        "y": "15.0"
      },
      "2018-04-25 19:51:39": {
        "x": "NaN",
        "y": "NaN"
      },
    }
  }
}

如您所见,苹果keys不是可连号。 这些对象中的每一个都有不同的长度,因此键为0的对象的长度为3,键为5的对象的长度为4,键为6的对象的长度为2。 现在,我希望键x和y的NaN值获得同一键的第一个时间戳的值。 所以,我想拥有的是这样:

{
  "apple": {
    "0": {
      "2018-04-25 19:51:38": {
        "x": "38.0",
        "y": "23.0"
      },
      "2018-04-25 19:51:39": {
        "x": "38.0", // <-- same value of the first element
        "y": "23.0" // <-- same value of the first element
      },
      "2018-04-25 19:51:40": {
        "x": "38.0", // <-- same value of the first element
        "y": "23.0" // <-- same value of the first element
      }
    },
    "5": {
      "2018-04-25 19:51:38": {
        "x": "50.0",
        "y": "35.0"
      },
      "2018-04-25 19:51:39": {
        "x": "50.0", 
        "y": "35.0" 
      },
      "2018-04-25 19:51:40": {
        "x": "50.0", // <-- same value of the first element
        "y": "35.0" // <-- same value of the first element
      },
      "2018-04-25 19:51:41": {
        "x": "50.0", // <-- same value of the first element
        "y": "35.0" // <-- same value of the first element
      },
    },
    "6": {
      "2018-04-25 19:51:34": {
        "x": "30.0",
        "y": "15.0"
      },
      "2018-04-25 19:51:39": {
        "x": "30.0", // <-- same value of the first element
        "y": "15.0" // <-- same value of the first element
      },
    }
  }
}

我不知道该怎么做:(

3 个答案:

答案 0 :(得分:1)

您可以将array#forEachObject.keys()一起使用来遍历对象的每个键。然后将第一个时间戳记xy的值存储在变量中,然后遍历内部对象的每个键并更新值为NaN的所有键的值。

let data = { "apple": { "0": { "2018-04-25 19:51:38": { "x": "38.0", "y": "23.0" }, "2018-04-25 19:51:39": { "x": "NaN", "y": "NaN" }, "2018-04-25 19:51:40": { "x": "NaN", "y": "NaN" } }, "5": { "2018-04-25 19:51:38": { "x": "50.0", "y": "35.0" }, "2018-04-25 19:51:39": { "x": "50.0", "y": "35.0" }, "2018-04-25 19:51:40": { "x": "NaN", "y": "NaN" }, "2018-04-25 19:51:41": { "x": "NaN", "y": "NaN" }, }, "6": { "2018-04-25 19:51:34": { "x": "30.0", "y": "15.0" }, "2018-04-25 19:51:39": { "x": "NaN", "y": "NaN" }, } } };
Object.keys(data.apple).forEach(k => {
  let x = 'NaN', y = 'NaN';
  Object.keys(data.apple[k]).sort().forEach((k1,i) => {
    if(i === 0) {
      x = data.apple[k][k1].x;
      y = data.apple[k][k1].y;
    } else {
      if(data.apple[k][k1].x === 'NaN')
        data.apple[k][k1].x = x;
      if(data.apple[k][k1].y === 'NaN')
        data.apple[k][k1].y = y;
    }
  });
});
console.log(data);

let data = { "apple": { "0": { "2018-04-25 19:51:38": { "x": "38.0", "y": "23.0" }, "2018-04-25 19:51:39": { "x": "NaN", "y": "NaN" }, "2018-04-25 19:51:40": { "x": "NaN", "y": "NaN" } }, "5": { "2018-04-25 19:51:38": { "x": "50.0", "y": "35.0" }, "2018-04-25 19:51:39": { "x": "50.0", "y": "35.0" }, "2018-04-25 19:51:40": { "x": "NaN", "y": "NaN" }, "2018-04-25 19:51:41": { "x": "NaN", "y": "NaN" }, }, "6": { "2018-04-25 19:51:34": { "x": "30.0", "y": "15.0" }, "2018-04-25 19:51:39": { "x": "NaN", "y": "NaN" }, } } },
  result = Object.keys(data.apple).reduce((r,k) => {
  let x = 'NaN', y = 'NaN';
  r.apple[k] = {};
  Object.keys(data.apple[k]).sort().forEach((k1,i) => {
    if(i === 0) {
      r.apple[k][k1] = {...data.apple[k][k1]};
      x = data.apple[k][k1].x;
      y = data.apple[k][k1].y;
    } else {
      if(data.apple[k][k1].x === 'NaN')
        r.apple[k][k1] = {x,y};
      if(data.apple[k][k1].y === 'NaN')
        r.apple[k][k1] = {x,y};
    }
  });
  return r;
}, {apple : {}});
console.log(result);

答案 1 :(得分:0)

for的本地语言比foreach更快。 不变的方式是另一个问题..必须在另一个问题中分开...但是..i会尝试您的要求... 和whoola ..还可以...尝试使用...克隆代码对象(不变的方式)

  
   var hola = {"apple":{"0":{"2018-04-25 19:51:38":{"x":"38.0","y":"23.0"},"2018-04-25 19:51:39":{"x":"NaN","y":"NaN"},"2018-04-25 19:51:40":{"x":"NaN","y":"NaN"}},"5":{"2018-04-25 19:51:38":{"x":"50.0","y":"35.0"},"2018-04-25 19:51:39":{"x":"50.0","y":"35.0"},"2018-04-25 19:51:40":{"x":"NaN","y":"NaN"},"2018-04-25 19:51:41":{"x":"NaN","y":"NaN"}},"6":{"2018-04-25 19:51:34":{"x":"30.0","y":"15.0"},"2018-04-25 19:51:39":{"x":"NaN","y":"NaN"}}}}
    
var original_var = clone(hola);

    for ( property in hola.apple ) {
     
        var property_sub = property 
        property_sub_keys = Object.keys( hola.apple[property_sub] );
        //console.log( property_sub_keys )
    
        for ( var i=0; i<property_sub_keys.length; i++){
          if (i==0) {
              x_ini = hola.apple[property_sub][property_sub_keys[i]].x
              y_ini = hola.apple[property_sub][property_sub_keys[i]].y
          }else{
            if ( hola.apple[property_sub][property_sub_keys[i]].x == "NaN" ){
                hola.apple[property_sub][property_sub_keys[i]].x = x_ini
            }
            if ( hola.apple[property_sub][property_sub_keys[i]].y == "NaN" ){
                hola.apple[property_sub][property_sub_keys[i]].y = y_ini
            }
          }
    
        } 
    
    
    }



function clone(obj) {
    var copy;

    // Handle the 3 simple types, and null or undefined
    if (null == obj || "object" != typeof obj) return obj;

    // Handle Date
    if (obj instanceof Date) {
        copy = new Date();
        copy.setTime(obj.getTime());
        return copy;
    }

    // Handle Array
    if (obj instanceof Array) {
        copy = [];
        for (var i = 0, len = obj.length; i < len; i++) {
            copy[i] = clone(obj[i]);
        }
        return copy;
    }

    // Handle Object
    if (obj instanceof Object) {
        copy = {};
        for (var attr in obj) {
            if (obj.hasOwnProperty(attr)) copy[attr] = clone(obj[attr]);
        }
        return copy;
    }

    throw new Error("Unable to copy obj! Its type isn't supported.");
}
    console.log(hola)
    console.log(original_var)
<script src="https://getfirebug.com/firebug-lite-debug.js"></script>

答案 2 :(得分:0)

使用Object.entries()上的Array#find()Object.values()获取有效对象,然后使用Object.assign()更新所有NaN

let data = { "apple": { "0": { "2018-04-25 19:51:38": { "x": "38.0", "y": "23.0" }, "2018-04-25 19:51:39": { "x": "NaN", "y": "NaN" }, "2018-04-25 19:51:40": { "x": "NaN", "y": "NaN" } }, "5": { "2018-04-25 19:51:38": { "x": "50.0", "y": "35.0" }, "2018-04-25 19:51:39": { "x": "50.0", "y": "35.0" }, "2018-04-25 19:51:40": { "x": "NaN", "y": "NaN" }, "2018-04-25 19:51:41": { "x": "NaN", "y": "NaN" }, }, "6": { "2018-04-25 19:51:34": { "x": "30.0", "y": "15.0" }, "2018-04-25 19:51:39": { "x": "NaN", "y": "NaN" }, } } };


Object.entries(data.apple).forEach(([k,v]) => {
   const valid = Object.values(v).find(({x,y})=> x !=='NaN' && y !=='NaN');
   Object.entries(v).filter(([_,{x,y}])=> x==='NaN' && y==='NaN')
                    .forEach(([k,v])=>Object.assign(v, valid))
   
});
console.log(data);
.as-console-wrapper {max-height: 100%!important;}