如何从循环向单个数组添加多个Json对象

时间:2019-04-04 13:54:17

标签: javascript arrays json loops

我正在进行外部api调用,这些调用返回json对象。进行所有调用后,我想将json对象的集合写入文件。但是,当我这样做时,它以错误的格式写入文件。

编辑:findPrices()函数在循环内被调用。

priceSearch1Array = [];

function findPrices(res) {

  (api.get({
    origin: A,
    destination: B,
  }).then(function(response) {

    priceSearchVar = JSON.stringify(response.result.data);
    priceSearch1Array.push(priceSearchVar);

  }).catch(function(error) {
    console.log('error and continue' + error);
  }))

}

所有API调用之后,该数组将发送到文件。

fs.writeFileSync('api/data/destinations3.json', priceSearch1Array);

当前输出为示例:

[{flight:"data", segments: { price:"23.22"}}],
[{flight:"data", segments: { price:"78.45"}}],
[{flight:"data", segments: { price:"48.45"}}]

当我需要它以以下格式写入文件时:

[ {flight:"data", segments: { price:"23.22"}},
  {flight:"data", segments: { price:"78.45"}},
  {flight:"data", segments: { price:"48.45"}} ]

我需要列表格式的json对象,然后将其添加到文件中,而不是每个对象添加一个数组。有办法吗?

3 个答案:

答案 0 :(得分:1)

    function findPrices(res) {

      (api.get({
        origin: A,
        destination: B,
      }).then(function(response) {
        let data = []

        try {
          // read the data and convert into json
          data = fs.readFileSync('api/data/destinations3.json', 'utf8')
          data = JSON.parse(data)
          data = Array.isArray(data) ? data : [data]
        } catch(err) {}

        const responseData = response.result.data
        const priceSearch1Array = JSON.stringify([ ...data, responseData ])

        fs.writeFileSync('api/data/destinations3.json', priceSearch1Array);

      }).catch(function(error) {
        console.log('error and continue' + error);
      }))

    }

答案 1 :(得分:0)

尝试仅用priceSearchVar = JSON.stringify(response.result.data);替换priceSearchVar =response.result.data,然后用priceSearch1Array.push(priceSearchVar)替换priceSearch1Array.push(JSON.stringify(...priceSearchVar))

或者也许可以只一行完成priceSearch1Array.push(JSON.stringify(...response.result.data))

答案 2 :(得分:0)

我认为可能是代码的结构使调试有些混乱。我已经为该示例重新格式化了格式,但是解决您遇到的问题不是必需的。

我认为可能有两个问题。

首先,当我们实际上想要一个对象数组时,我们得到了一个对象数组。如果按以下函数所示展平数组,这很容易解决。

第二,我们正在将原始对象写入文件。据我了解,经过一些测试,fs会将写入的数据作为字符串写入文件。这意味着它将使用相当简单的转换,并且您的对象将如您所见以[Object object]的形式出现。为了解决这个问题,我们可以使用JSON.stringify获得更合适的转换。我已经模拟了fs和api调用,但是该示例为您提供了一个大概的想法。

我也将其转换为使用mapPromise.all,而不是从循环中推送到数组。我觉得用这种方式更容易理解,如果没有意义,请随时发表评论,我将进行更详细的介绍。

const api = {
  get: data => new Promise(res => {
    setTimeout(() => res([data]), 1000)
  })
}

const fs = {
  writeFileSync: (location, data) => {
    console.log(
      `writing data ${data} to ${location}`
    );
    console.log('=====================');
  }
}

const data = [
  {A: 'test', B: 'another test'},
  {A: 'test2', B: 'another test2'},
];

const makeApiCallFromDataItem = dataItem => api.get({
  origin: dataItem.A,
  destination: dataItem.B,
});

const callApiForAllDataItems = data => Promise
  .all(data.map(makeApiCallFromDataItem))

const flatten = dataIn => dataIn.reduce((prev, curr) => [
  ...prev,
  ...curr
])

callApiForAllDataItems(data)
  .then(data => {
    fs.writeFileSync('api/data/destinations3.json', data)
  })
  
callApiForAllDataItems(data)
  .then(data => {
    fs.writeFileSync('api/data/destinations3.json', JSON.stringify(data))
  })
  
callApiForAllDataItems(data)
  .then(data => {
    const flatData = flatten(data);
    fs.writeFileSync('api/data/destinations3.json', JSON.stringify(flatData))
  })