简体   繁体   中英

How can I create a dynamic array based on another array in javascript/typescript?

I want to create an array to loop over one of the parameters of the first array (in this example, the desired parameter is the DT ) and check whether we have data for different applications on those dates. If we have it, it will put its value (in the second array) and if we don't have it, it will put 0.

What I did was also with const pluck = (arr, key) => arr.map(i => i[key]); , I obtained the desired field dates (but they had duplicate values). To remove duplicate values I used dates = [...new Set(dates)]; and finally looped over the final values and wrote a series of codes, but I didn't get what I wanted (Expected Array in below).

first_array = [
  {
    DT: "2022-01-01",
    APP: "Application 1",
    SPEED: 1547,
  },
  {
    DT: "2022-01-01",
    APP: "Application 2",
    SPEED: 685,
  },
  {
    DT: "2022-01-02",
    APP: "Application 1",
    SPEED: 500,
  },
  {
    DT: "2022-01-02",
    APP: "Application 2",
    SPEED: 300,
  },
  {
    DT: "2022-01-02",
    APP: "Application 3",
    SPEED: 600,
  },
  {
    DT: "2022-01-03",
    APP: "Application 1",
    SPEED: 1000,
  },
]

Expected Array :

desire_array = [
  {
    Name: "Application1",
    Values: [1547, 500, 1000],
    ValuesWithDate: [{x: '2022-01-01', y: 1547}, {x: '2022-01-02', y: 500}, {x: '2022-01-03', y: 1000}],
  },
  {
    Name: "Application2",
    Values: [685, 300, 0],
    ValuesWithDate: [{x: '2022-01-01', y: 685}, {x: '2022-01-02', y: 300}, {x: '2022-01-03', y: 0}],
  },
  {
    Name: "Application3",
    Values: [0, 600, 0],
    ValuesWithDate: [{x: '2022-01-01', y: 0}, {x: '2022-01-02', y: 600}, {x: '2022-01-03', y: 0}],
  },
]

The reason I need to do this is to create a series that I can use to display the chart with ApexCharts.

Real data can also be displayed from this api as JSON.

You can try with something like this:

const convertArray = (arr) => arr.reduce((prev, current) => {
    const existingIndex = prev.findIndex((p) => p.Name === current.APP);
  if (existingIndex > -1) {
    const currentApp = prev[existingIndex];
    currentApp.Values.push(current.SPEED);
    currentApp.ValuesWithDate.push({x: current.DT, y: current.SPEED});
    prev[existingIndex] = currentApp;
  } else {
    prev.push({Name: current.APP, Values: [current.SPEED], ValuesWithDate:[{x: current.DT, y: current.SPEED}]})
  }
    return prev;
}, []);

And use it like this:

const desire_array = convertArray(first_array)
    const convert = (dates, data) => {
    return Object.values(data.reduce((acc, curr) => {
        if (!acc[curr.APP]) {
            acc[curr.APP] = {
                name: curr.APP,
                valuesWithDate: []
            };
        }
        acc[curr.APP].valuesWithDate.push({
            x: curr.DT,
            y: curr.SPEED
        });
        return acc;
    }, {})).map((dataWithoutGaps) => {
        const valuesWithDate = [...new Set(dates)].map(date => {
            const el = dataWithoutGaps.valuesWithDate.find(e => e.x === date);
            return {
                x: date,
                y: el ? el.y : 0
            };
        });
        return {
            ValuesWithDate: valuesWithDate,
            Values: valuesWithDate.map(e => e.y),
            Name: dataWithoutGaps.name
        }
    });
};



console.log(convert(first_array.map(e => e.DT), first_array));

Expected:

[{"ValuesWithDate":[{"x":"2022-01-01","y":1547},{"x":"2022-01-02","y":500},{"x":"2022-01-03","y":1000}],"Values":[1547,500,1000],"Name":"Application 1"},{"ValuesWithDate":[{"x":"2022-01-01","y":685},{"x":"2022-01-02","y":300},{"x":"2022-01-03","y":0}],"Values":[685,300,0],"Name":"Application 2"},{"ValuesWithDate":[{"x":"2022-01-01","y":0},{"x":"2022-01-02","y":600},{"x":"2022-01-03","y":0}],"Values":[0,600,0],"Name":"Application 3"}]

You can do:

 const first = [{DT: '2022-01-01',APP: 'Application 1',SPEED: 1547,},{DT: '2022-01-01',APP: 'Application 2',SPEED: 685,},{DT: '2022-01-02',APP: 'Application 1',SPEED: 500,},{DT: '2022-01-02',APP: 'Application 2',SPEED: 300,},{DT: '2022-01-02',APP: 'Application 3',SPEED: 600,},{DT: '2022-01-03',APP: 'Application 1',SPEED: 1000,}] const dates = [...new Set(first.map(({ DT }) => DT))] const apps = [...new Set(first.map(({ APP }) => APP))] const result = apps.reduce((acc, app) => { const appData = Object.assign( {}, { Name: app.replace(/ /, ''), Values: [], ValuesWithDate: [], } ) dates.forEach((date) => { const data = first.find(({ DT, APP }) => DT === date && APP === app) appData.ValuesWithDate.push({ x: date, y: data? data.SPEED: 0 }) appData.Values.push(data? data.SPEED: 0) }) acc.push(appData) return acc }, []) console.log(result)

Your expected result can be get by this code.

let filtered_app = new Set();
const obj = [];

first_array.forEach(item=>{
  filtered_app.add(item.APP);
});
filtered_app.forEach(app =>{
  first_array.forEach(item =>{
    if(item.APP == app){
      const exists = obj.findIndex(elem => elem.Name == app);
      if(exists != '-1'){
        obj[exists].Values.push(item.SPEED);
        obj[exists].ValuesWithDate.push({x: item.DT, y: item.SPEED});
      }
      else{
        obj.push({Name: app, Values: [item.SPEED], ValuesWithDate: [{x: item.DT, y: item.SPEED}]});
      }
    }
  });
});
console.log(obj);

Hope it helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM