Javascript按摩数据到新阵列

问题描述 投票:1回答:4

编辑

所以我想我应该再深入研究一下这个问题。我目前正在使用HighCharts JS。要在highcharts中显示数据,我必须得到如下最终数据:

[
  {
    name: 'Performing',
    data: [1941404, 1028717, 697370, 0, 0, 0]
  },
  {
    name: 'Non performing',
    data: [0, 0, 0, 1759908, 890857, 280235]
  },
  {
    name: 'Substandard',
    data: [0, 0, 863825, 0, 0, 0]
  },
  {
    name: 'Written-off',
    data: [0, 0, 0, 0, 0, 77146]
  }
]

“数据”是一个由6个对象组成的数组,用于填充图表的xAxis。

但是,我有以下通过MongoDb提供的数据

[
  {
    "_id": {
      "data": "90 - 180",
      "status": "Non Performing"
    },
    "value": 1759908
  },
  {
    "_id": {
      "data": "360",
      "status": "Written-off"
    },
    "value": 77146
  },
  {
    "_id": {
      "data": "360",
      "status": "Non Performing"
    },
    "value": 280235
  },
  {
    "_id": {
      "data": "30 - 90",
      "status": "Substandard"
    },
    "value": 863825
  },
  {
    "_id": {
      "data": "30 - 90",
      "status": "Performing"
    },
    "value": 697370
  },
  {
    "_id": {
      "data": "180 - 360",
      "status": "Non Performing"
    },
    "value": 890857
  },
  {
    "_id": {
      "data": "0 - 30",
      "status": "Performing"
    },
    "value": 1028717
  },
  {
    "_id": {
      "data": "0",
      "status": "Performing"
    },
    "value": 1941404
  }
]

我需要过滤后面的代码,以便它像以前的代码一样结束。非常重要的是,在数据数组中,我们最终得到6个对象,以确保我们填充Highcharts的整个xAxis,因此我们看到很多零,没有提供数据。

我真的希望这可以解决问题。感谢所有有帮助的人。我为偏离这么模糊而道歉。

快速注意数据阵列的顺序如下:0,0-30,30-90,90-180,180-360,360

javascript arrays object
4个回答
2
投票

使用.reduce.map方法到达那里。您可以使用.reduce方法连接数据,以实现您想要的效果,然后使用.map方法将其塑造回数组。

见下文:

const data = [
  {
    "_id": { "data": "90 - 180", "status": "Non Performing" }, "value": 1759908
  },
  {
    "_id": { "data": "360", "status": "Written-off" }, "value": 77146
  },
  {
    "_id": { "data": "360", "status": "Non Performing" }, "value": 280235
  },
  {
    "_id": { "data": "30 - 90", "status": "Substandard" }, "value": 863825
  },
  {
    "_id": { "data": "30 - 90", "status": "Performing" }, "value": 697370
  },
  {
    "_id": { "data": "180 - 360", "status": "Non Performing" }, "value": 890857
  },
  {
    "_id": { "data": "0 - 30", "status": "Performing" }, "value": 1028717
  },
  {
    "_id": { "data": "0", "status": "Performing" }, "value": 1941404
  }
]

const reducedMap = data.reduce((reducedMap, entry) => {
    if(!reducedMap[entry._id.status]) reducedMap[entry._id.status] = [];
    reducedMap[entry._id.status].push(entry.value);
    return reducedMap;
}, {});

const reducedArray = Object.keys(reducedMap).map( key => ({
    name: key,
    data: reducedMap[key]
}))

编辑

因此,在阅读了您的评论和其他答案之后,我想出了这个解决方案,它可以满足您的需求(请阅读其中的注释块以便了解):

// Define How the data is structured
const orderIdx = ["0", "0 - 30", "30 - 90", "90 - 180", "180 - 360", "360"];
const allStatuses = ["Performing", "Non Performing", "Substandard" , "Written-off"];

// Construct the mapping
const mappedIdx = orderIdx.reduce((m, key)=> { return { ...m, [key]: 0 } }, {}) 
    // mappedIdx = { "0": 0, "0-30": 0, "30-90": 0, "90-180": 0, "180-360": 0, "360": 0 }
const mappedInput = allStatuses.reduce((m, name) => { 
    return {...m, [name]: Object.assign({},mappedIdx) };
}, {})
    // mappedInput = { 
    //  "Performing": { "0": 0, "0-30": 0, "30-90": 0, "90-180": 0, "180-360": 0, "360": 0 }, 
    //  "Non Performing": { "0": 0, "0-30": 0, "30-90": 0, "90-180": 0, "180-360": 0, "360": 0 }, 
    //  "Substandard" : { "0": 0, "0-30": 0, "30-90": 0, "90-180": 0, "180-360": 0, "360": 0 }, 
    //  "Written-off": { "0": 0, "0-30": 0, "30-90": 0, "90-180": 0, "180-360": 0, "360": 0 }, 
    // }

// Loop on data
data.forEach( row => {
    mappedInput[row._id.status][row._id.data] = row.value
})

const reducedArray = Object.keys(mappedInput).map( key => ({
    name: key,
    data: Object.keys(mappedInput[key]).map( dataKey => mappedInput[key][dataKey])
}))

// reducedArray = [
//   {
//     name: 'Performing',
//     data: [1941404, 1028717, 697370, 0, 0, 0]
//   },
//   {
//     name: 'Non performing',
//     data: [0, 0, 0, 1759908, 890857, 280235]
//   },
//   {
//     name: 'Substandard',
//     data: [0, 0, 863825, 0, 0, 0]
//   },
//   {
//     name: 'Written-off',
//     data: [0, 0, 0, 0, 0, 77146]
//   }
// ]

您还可以将其简化为一个简短的功能:

function summarizeData(data, orderIdx, allStatuses){
    const mappedIdx = orderIdx.reduce((m, key)=> { return { ...m, [key]: 0 } }, {}) 
    const mappedInput = allStatuses.reduce((m, name) => { 
        return {...m, [name]: Object.assign({},mappedIdx) };
    }, {})

    data.forEach( row => {
        mappedInput[row._id.status][row._id.data] = row.value
    })

    return Object.keys(mappedInput).map( key => ({
        name: key,
        data: Object.keys(mappedInput[key]).map( dataKey => mappedInput[key][dataKey])
    }))
}
summarizeData(data, ["0", "0 - 30", "30 - 90", "90 - 180", "180 - 360", "360"], ["Performing", "Non Performing", "Substandard" , "Written-off"])

请注意,您需要对orderIdxallStatuses进行参数化,因为仅仅通过观察它们应该是什么来表达它并不是很清楚。此外,请确保放置一个验证这些实际上是唯一可以采用的值的进程。


0
投票

使用the reduce method,只需记住指定初始对象。

newData = yourData.reduce(function(element, accumulator){
    if (accumulator already has element with name property equalling to element.status) {
        // push value to existing array
    } else {
        // add new element
    }
}, {}); // second argument is just an empty object

0
投票

通常,您希望您的代码尽可能简洁,同时仍然讲述它接受并返回的对象的故事。类似下面的内容将描述接受的未格式化对象,描述对其执行的转换并隐式描述函数返回的对象。

function generateFormattedArray(unformattedDataArray) {
  const flattenedDataArray = unformattedDataArray.forEach((obj) => { status: obj['_id'].status, value: obj.value });
  return [
    {
        name: 'Performing',
        data: flattenedDataArray.filter((obj) => obj.status === 'Performing').forEach((obj) => obj.value),
    },
    {
        name: 'Non performing',
        data: flattenedDataArray.filter((obj) => obj.status === 'Non performing').forEach((obj) => obj.value),
    },
    {
        name: 'Substandard',
        data: flattenedDataArray.filter((obj) => obj.status === 'Substandard').forEach((obj) => obj.value),
    },
    {
        name: 'Written-off',
        data: flattenedDataArray.filter((obj) => obj.status === 'Written-off').forEach((obj) => obj.value),
    },
  ];
}

虽然说实话,除非有这种嵌套格式的特定用例...我宁愿使用在第2行创建的flattenedDataArray。


-1
投票

你可以这样做:

var originalArray = [
  {
    "_id": {
      "data": "90 - 180",
      "status": "Non Performing"
    },
    "value": 1759908
  },
  {
    "_id": {
      "data": "360",
      "status": "Written-off"
    },
    "value": 77146
  },
  {
    "_id": {
      "data": "360",
      "status": "Non Performing"
    },
    "value": 280235
  },
  {
    "_id": {
      "data": "30 - 90",
      "status": "Substandard"
    },
    "value": 863825
  },
  {
    "_id": {
      "data": "30 - 90",
      "status": "Performing"
    },
    "value": 697370
  },
  {
    "_id": {
      "data": "180 - 360",
      "status": "Non Performing"
    },
    "value": 890857
  },
  {
    "_id": {
      "data": "0 - 30",
      "status": "Performing"
    },
    "value": 1028717
  },
  {
    "_id": {
      "data": "0",
      "status": "Performing"
    },
    "value": 1941404
  }
];

var newArray = [
    {
        'name': 'Performing',
    'data': []
    },
    {
        'name': 'Non Performing',
    'data': []
    },
    {
        'name': 'Substandard',
    'data': []
    },
    {
        'name': 'Written-off',
    'data': []
    }  
];

for (var x = 0; x < originalArray.length; x++) {
    if (originalArray[x]._id.status === 'Performing') {
    for (var y = 0; y < newArray.length; y++) {
        if (newArray[y].name === 'Performing') {
        newArray[y].data.push(originalArray[x]._id.data)
      }
    }
  } else if (originalArray[x]._id.status === 'Non Performing') {
    for (var y = 0; y < newArray.length; y++) {
        if (newArray[y].name === 'Non Performing') {
        newArray[y].data.push(originalArray[x]._id.data)
      }
    }
  } else if (originalArray[x]._id.status === 'Substandard') {
    for (var y = 0; y < newArray.length; y++) {
        if (newArray[y].name === 'Substandard') {
        newArray[y].data.push(originalArray[x]._id.data)
      }
    }
  } else if (originalArray[x]._id.status === 'Written-off') {
    for (var y = 0; y < newArray.length; y++) {
        if (newArray[y].name === 'Written-off') {
        newArray[y].data.push(originalArray[x]._id.data)
      }
    }
  }
}

console.log(newArray);

工作示例:https://jsfiddle.net/extro3tw/

© www.soinside.com 2019 - 2024. All rights reserved.