提取对象数组中未知键的值

时间:2018-06-13 07:53:13

标签: javascript arrays object

我从具有未知数量密钥的外部源获取JSON。例如,结构如下:

data = [{
id: 1,
testObject_1_color: "red",
testObject_1_shape: "triangle",
testObject_2_color: "blue",
testObject_2_shape: "line",
},{
id: 2,
testObject_1_color: "green"
testObject_1_shape: "triangle",
},{
id: 3,
testObject_1_color: "brown",
testObject_1_shape: "square",
testObject_2_color: "black",
testObject_2_shape: "circle",
testObject_3_color: "orange"
testObject_3_shape: "square",
}]

要处理这些数据,我需要将其转换为更有用的内容,例如:

data = [
{object:1, color:"red", shape:"triangle"},
{object:2, color:"blue", shape:"line"},
{object:3, color:"green", shape:"triangle"}
]

testObject_x_color / shape的数量是未定义的,理论上可以是介于0和100之间的任何数字。有人知道如何在不询问100次if data.hasOwnProperty('testObject_x_color')...的情况下浏览该集合吗?

2 个答案:

答案 0 :(得分:1)

使用reg和es5数组函数。



let data = [{
    id: 1,
    testObject_1_color: 'red',
    testObject_1_shape: 'triangle',
    testObject_2_color: 'blue',
    testObject_2_shape: 'line'
  },
  {
    id: 2,
    testObject_1_color: 'green',
    testObject_1_shape: 'triangle'
  },
  {
    id: 3,
    testObject_1_color: 'brown',
    testObject_1_shape: 'square',
    testObject_2_color: 'black',
    testObject_2_shape: 'circle',
    testObject_3_color: 'orange',
    testObject_3_shape: 'square'
  }
]
let regId = /testObject_(\d{1,3})_(color|shape)/
let res = data
  .reduce((re, obj) => {
    Reflect.ownKeys(obj)
      .filter(key => key !== 'id')
      .forEach(key => {
        let id = obj.id + '' + key.match(regId)[1]
        let isFind = re.find(o => o.id === id)
        if (!isFind) {
          re.push({
            id: obj.id + '' + key.match(regId)[1],
            color: obj[key]
          })
        } else {
          isFind.shape = obj[key]
        }
      })
    return re
  }, [])
  .map(({
    id,
    color,
    shape
  }, index) => ({
    id: index + 1,
    color,
    shape
  }))
console.log(res)




答案 1 :(得分:1)

另一个带有几个循环的解决方案:



var data = [{
  id: 1,
  testObject_1_color: "red",
  testObject_1_shape: "triangle",
  testObject_2_color: "blue",
  testObject_2_shape: "line"
}, {
  id: 2,
  testObject_1_color: "green",
  testObject_1_shape: "triangle"
}, {
  id: 3,
  testObject_1_color: "brown",
  testObject_1_shape: "square",
  testObject_2_color: "black",
  testObject_2_shape: "circle",
  testObject_3_color: "orange",
  testObject_3_shape: "square"
}];

var sorted = data.reduce(function(result, item) {
  
  // Temp object to store all properties 
  var tmp = {};
  
  // Get all keys of the object
  Object.keys(item).forEach(function(k) {
  
    // Split by underscore
    var parts = k.split('_');
    
    // Process only properties with similar to testObject_1_color names
    // and skip other e.g. id
    if (parts.length === 3) {
      if (!tmp[parts[1]]) {
        tmp[parts[1]] = {};
      }
      tmp[parts[1]][parts[2]] = item[k];
    }
  });
  
  // Fill data in the result array
  Object.values(tmp).forEach(function (pair, i) {
    result.push(pair);
  });
  
  return result;
}, []);

for (var i = 0; i < sorted.length; i++) {
  console.log('object ' + (i + 1) + ': ', sorted[i]);
}
&#13;
&#13;
&#13;