arraysangulartypescriptarraylistremap

Remap structure parent object base on child array data and length object


I am trying remap structure data parent base on child array data and length. It's possible to do? Structure array it's good or i need change array object from backend?

There is no id in child arrays.

This is what i have done

this.arrays = [
  {
    id: '1',
    idbid: '0000000001618',
    name: 'ebi',
    rate: '400',
    bid: [
      {
        bid: 10000,
        date: '2022/12/12',
        value: 5000,
      },
      {
        bid: 10000,
        date: '2022/12/14',
        value: 8100,
      },
      {
        bid: 15000,
        date: '2022/12/15',
        value: 8100,
      },
    ],
  },
  {
    id: '2',
    idbid: '0000000001618',
    name: 'bio',
    rate: '100',
    bid: [
      {
        bid: 8000,
        date: '2022/12/13',
        value: 8000,
      },
    ],
  },
];

// merge all item bid in child array
let allVal: any = [];
allVal = allVal.concat(this.arrays.map((data) => data.bid).flat());
console.log(allVal);

// get unique bid
var uniqueData = [];
allVal.forEach((item) => {
  let count = uniqueData.filter((x) => x.value == item.value).length;

  if (count == 0) {
    uniqueData.push(item);
  }
});
console.log(uniqueData);

// find and merge into parent array
const newArrays = uniqueData.map((obj) => {
  return this.arrays.find((data) =>
    data.bid.some((val) => val.value == obj.value)
  );
});
console.log(newArrays);

// remap structure custom arrays of parent
const remapArrays = newArrays.map((obj, index) => {
  return {
    id: index + 1,
    idbid: obj.idbid,
    name: obj.name,
    rate: obj.rate,
    bid: obj.bid[index]?.bid,
    date: obj.bid[index]?.date,
    value: obj.bid[index]?.value,
  };
});
console.log(remapArrays);

but the result is like this

[
  {
    id: '1',
    idbid: '0000000001618',
    name: 'ebi',
    rate: '400',
    bid: 10000,
    date: '2022/12/12',
    value: 5000,
  },
  {
    id: '2',
    idbid: '0000000001618',
    name: 'bio',
    rate: '100',
    bid: 10000,
    date: '2022/12/13',
    value: 8100,
  },
  {
    id: '3',
    idbid: '0000000001618',
    name: 'ebi',
    rate: '400',
    bid: undefined,
    date: undefined,
    value: undefined,
  },
];

and here is what expected output

// output final that exptected
this.customArrays = [
  {
    id: '1',
    idbid: '0000000001618',
    name: 'ebi',
    rate: '400',
    bid: 10000,
    date: '2022/12/12',
    value: 5000,
  },
  {
    id: '2',
    idbid: '0000000001618',
    name: 'bio',
    rate: '100',
    bid: 8000,
    date: '2022/12/13',
    value: 8000,
  },
  {
    id: '3',
    idbid: '0000000001618',
    name: 'ebi',
    rate: '400',
    bid: 15000,
    date: '2022/12/15',
    value: 8100,
  },
];

Here is link for test Stackblitz


Solution

  • There are some things that should be defined more clearly in the question:

    In my answer, I'll be assuming that the answer is "yes" to both.

    allVal.concat(this.arrays.map((data) => data.bid).flat());
    

    We're losing the values that are unique to each parent element: for example, the value of "rate" is "400" for the first parent element and "100" for the second. So before flattening, we need to map each of the bid arrays, so each child element includes the data from the parent element:

    // merge all item bids in child arrays
    const allVal = this.arrays
      .map((dataWithBids) => {
        const { id, idbid, name, rate, bid: bidArr } = dataWithBids;
        // add data from the parent element to each bid
        return bidArr.map((bidData) => ({
          idbid,
          name,
          rate,
          ...bidData,
        }));
      })
      .flat();
    

    In the following step, getting only unique values can be done the same way as you did, or using the array some method:

    // get unique bids
    const uniqueData = [];
    allVal.forEach((item) => {
      const exists = uniqueData.some((x) => x.value == item.value);
    
      if (!exists) {
        uniqueData.push(item);
      }
    });
    

    At this point we have the correct values, and we need to order them by date and add ids:

    const sorted = uniqueData
      // sort by date
      .sort(
        (bidData1, bidData2) =>
          Date.parse(bidData1.date) - Date.parse(bidData2.date)
      )
      // add ids
      .map((bidData, index) => ({
        ...bidData,
        id: index + 1 // or (index + 1).toString(),
      }));
    

    The result of the above sorted array matches the expected output.