对象数组:为每个具有值

时间:2017-11-01 15:23:50

标签: javascript arrays object foreach

我有一个从CSV文件中提取的对象数组,如下所示:

    const data = [
  { name: 'p1', 'date started': 'April 2007', Houston: '375', Dallas: '508', Austin: '', 'El Paso': '1232' },
  { name: 'p2', 'date started': 'April 2017', Houston: '', Dallas: '', Austin: '', 'El Paso': '43' },
  { name: 'p3', 'date started': 'June 2012', Houston: '18789', Dallas: '', Austin: '8977', 'El Paso': '6754656' },
  { name: 'p4', 'date started': 'December 2015', Houston: '878', Dallas: '4556', Austin: '987', 'El Paso': '1456232' }
]

我正在创建一些数据的图表和表格,需要创建两个新的键,“location”和“value”,并为每个对象中的每个位置值创建新对象,如下所示:

    const newData = [
  { location: 'Houston', value: '375', name: 'p1', 'date started': 'April 2007' },
  { location: 'Dallas', value: '508', name: 'p1', 'date started': 'April 2007' },
  { location: 'El Paso', value: '1232', name: 'p1', 'date started': 'April 2007' },
  { location: 'El Paso', value: '43', name: 'p2', 'date started': 'April 2017' },
  { location: 'Houston', value: '18789', name: 'p3', 'date started': 'June 2012' },
  { location: 'Austin', value: '8977', name: 'p3', 'date started': 'June 2012' },
  { location: 'El Paso', value: '6754656', name: 'p3', 'date started': 'June 2012' },
  { location: 'Houston', value: '878', name: 'p4', 'date started': 'December 2015' },
  { location: 'Dallas', value: '4556', name: 'p4', 'date started': 'December 2015' },
  { location: 'Austin', value: '987', name: 'p4', 'date started': 'December 2015' },
  { location: 'El Paso', value: '1456232', name: 'p4', 'date started': 'December 2015' }
]

我之前必须为类似项目执行此操作,时间不够,最后手动编辑原始CSV文件。我宁愿不再这样做了。到目前为止,我已经尝试了map / forEach和Object.keys的各种组合,没有运气。

任何想法都会非常感激!

4 个答案:

答案 0 :(得分:2)

您可以迭代对象的所有键并排除不需要的propoerties并为结果集构建新对象。



var data = [{ name: 'p1', 'date started': 'April 2007', Houston: '375', Dallas: '508', Austin: '', 'El Paso': '1232' }, { name: 'p2', 'date started': 'April 2017', Houston: '', Dallas: '', Austin: '', 'El Paso': '43' }, { name: 'p3', 'date started': 'June 2012', Houston: '18789', Dallas: '', Austin: '8977', 'El Paso': '6754656' }, { name: 'p4', 'date started': 'December 2015', Houston: '878', Dallas: '4556', Austin: '987', 'El Paso': '1456232' }],
    result = data.reduce(function (r, o) {
        Object.keys(o).forEach(function (k)  {
            if (['name', 'date started'].includes(k) || !o[k]) {
                return;
            }
            r.push({ location: k, value: o[k], name: o.name, 'date started': o['date started'] });
        });
        return r;
    }, []);

console.log(result);

.as-console-wrapper { max-height: 100% !important; top: 0; }




答案 1 :(得分:1)

您可以遍历所有items这些旧对象,然后遍历旧对象中的所有键并基于此构建新数组,就像这样



const data = [
        { name: 'p1', 'date started': 'April 2007', Houston: '375', Dallas: '508', Austin: '', 'El Paso': '1232' },
        { name: 'p2', 'date started': 'April 2017', Houston: '', Dallas: '', Austin: '', 'El Paso': '43' },
        { name: 'p3', 'date started': 'June 2012', Houston: '18789', Dallas: '', Austin: '8977', 'El Paso': '6754656' },
        { name: 'p4', 'date started': 'December 2015', Houston: '878', Dallas: '4556', Austin: '987', 'El Paso': '1456232' }
    ];

function transform() {
    
    var newObjects = [];
    data.forEach(item => {
        Object.keys(item).forEach(keyName => {
            if (keyName !== "name" && keyName !== "date started") {
                newObjects.push({
                    location: keyName,
                    value: item[keyName],
                    ["date started"]: item["date started"],
                    name: item["name"]
                })
            }
        });
    });
    return newObjects;
}

console.log(transform(data));




希望这有帮助

答案 2 :(得分:1)

通过解构分配和休息/传播语法,这变得非常干净。



const data = [
  { name: 'p1', 'date started': 'April 2007', Houston: '375', Dallas: '508', Austin: '', 'El Paso': '1232' },
  { name: 'p2', 'date started': 'April 2017', Houston: '', Dallas: '', Austin: '', 'El Paso': '43' },
  { name: 'p3', 'date started': 'June 2012', Houston: '18789', Dallas: '', Austin: '8977', 'El Paso': '6754656' },
  { name: 'p4', 'date started': 'December 2015', Houston: '878', Dallas: '4556', Austin: '987', 'El Paso': '1456232' }
];

const result = data.reduce((res, obj) => {
  const date_started = obj["date started"];
  delete obj["date started"];
  const {name, ...rest} = obj;
  
  return [...res, ...Object.entries(rest).map(([k,v]) =>
    ({location:k, value:v, name:name, 'date started':date_started})
  )]
}, []);

console.log(result);




如果您希望避免使用对象文字中的rest参数,并且您不想要空位置,则可以创建用于排除非位置键的Set,并使用truthy评估以排除不受欢迎的位置。



var data = [{ name: 'p1', 'date started': 'April 2007', Houston: '375', Dallas: '508', Austin: '', 'El Paso': '1232' }, { name: 'p2', 'date started': 'April 2017', Houston: '', Dallas: '', Austin: '', 'El Paso': '43' }, { name: 'p3', 'date started': 'June 2012', Houston: '18789', Dallas: '', Austin: '8977', 'El Paso': '6754656' }, { name: 'p4', 'date started': 'December 2015', Houston: '878', Dallas: '4556', Austin: '987', 'El Paso': '1456232' }];

var exc = new Set(['name', 'date started']);
var result = data.reduce((r, o) =>
    [
      ...r, 
      ...Object.entries(o)
        .filter(([k, v]) => v && !exc.has(k))
        .map(([k, v]) => ({ location: k, value: v, name: o.name, 'date started': o['date started'] }))
    ]
, []);

console.log(result, null, 2);




答案 3 :(得分:1)

使用完全通用的方法,OP控制所有键值对,必须为每个新创建的数据项“按原样”分配...甚至是每个数据输入元组的代理键...

var data = [
  { name: 'p1', 'date started': 'April 2007', Houston: '375', Dallas: '508', Austin: '', 'El Paso': '1232' },
  { name: 'p2', 'date started': 'April 2017', Houston: '', Dallas: '', Austin: '', 'El Paso': '43' },
  { name: 'p3', 'date started': 'June 2012', Houston: '18789', Dallas: '', Austin: '8977', 'El Paso': '6754656' },
  { name: 'p4', 'date started': 'December 2015', Houston: '878', Dallas: '4556', Austin: '987', 'El Paso': '1456232' }
];

var newData = data.reduce(function (collector, dataItem) {
  var
  //itemEntryList = Object.entries(dataItem); // if available, otherwise next line ...
    itemEntryList = Object.keys(dataItem).map(function (key) {
      return [key, dataItem[key]];
    }),
    assignerList = [],
    assignerKey,
    idx = -1,
    keyForDataKey = collector.keyForDataKey,
    keyForDataValue = collector.keyForDataValue,
    protectedKeyList = collector.protectedKeyList;

  // implement a local `reject` ... for all key value pairs that have to be copied "as is".
  while ((assignerKey = itemEntryList[++idx]) && (assignerKey = assignerKey[0])) {
    if (protectedKeyList.some(function (protectedKey) {
      return (assignerKey === protectedKey);
    })) {
      assignerList.push({ key: assignerKey, value: itemEntryList[idx][1] });
      itemEntryList.splice(idx, 1);
      --idx;
    }
  }
  // create new data-item base-structures from the remaining `dataItem` tuples after the `reject` step.
  var dataItemList = itemEntryList.reduce(function (itemList, dataTuple) {

    var tupleValue = dataTuple[1];
    if (tupleValue) {
      var newDataItem = {};
      newDataItem[keyForDataKey] = dataTuple[0];
      newDataItem[keyForDataValue] = tupleValue;

      itemList.push(newDataItem);
    //itemList.push({ location: dataTuple[0], value: tupleValue });
    }
    return itemList;

  }, []);

  // for each new data item ...
  dataItemList.map(function (newDataItem) {
    return assignerList.reduce(function (dataItem, assignerItem) {

      // ... reassign all formerly rejected key value pairs that have to be copied "as is".
      dataItem[assignerItem.key] = assignerItem.value;
      return dataItem;

    }, newDataItem)
  });

  // collect all new data items.
  collector.dataItemList = collector.dataItemList.concat(dataItemList);

  return collector;

}, {

  keyForDataKey:    'location',
  keyForDataValue:  'value',

  protectedKeyList: ['name', 'date started'],
  dataItemList:     []

}).dataItemList;


console.log('data : ', data);
console.log('newData : ', newData);
.as-console-wrapper { max-height: 100%!important; top: 0; }