Home > Back-end >  Javascript, getting past values for an array of objects
Javascript, getting past values for an array of objects

Time:02-05

I have a JavaScript array of objects which looks like

var myarr = [
{'xx':'2023-01-01,,1'},
{'ss':'2023-01-01,2,1.2'},
{'dd':'2023-01-01,4,'},
{'rr':'2023-01-01,,'},
{'ff':'2023-01-01,,'},
{'gg':'2023-01-01,,'}
];

The array is actually much bigger than that, but I have cut it down for testing purposes, some of my arrays are thousands of lines long

Each object contains a date and two comma-separated values, although I have some rows which contain 3 or 4 comma separate values

What I need to do, is if any blank comma-separated value is found on any row then get the previous comma separated value from that position to a maximum of 2 times going back, although I may need to change that to a bigger number in the future

So with my example, I would get the following output

var myarr = [
{'xx':'2023-01-01,,1.6'},
{'ss':'2023-01-01,2,1.2'},
{'dd':'2023-01-01,4,1.2'},
{'rr':'2023-01-01,4,1.2'},
{'ff':'2023-01-01,4,'},
{'gg':'2023-01-01,,'}
];

I have tried to solve this with

var myarr = [
{'xx':'2023-01-01,,1'},
{'ss':'2023-01-01,2,1.2'},
{'dd':'2023-01-01,4,'},
{'rr':'2023-01-01,,'},
{'ff':'2023-01-01,,'},
{'gg':'2023-01-01,,'}
];

var maxAttempts = 3;

for (var i = 0; i < myarr.length; i  ) {
  var obj = myarr[i];
  var values = Object.values(obj)[0].split(",");
  var date = values[0];
  var value1 = values[1];
  var value2 = values[2];
  for (var j = 1; j <= maxAttempts; j  ) {
    if (!value1) {
      value1 = (myarr[i-j] && Object.values(myarr[i-j])[0].split(",")[1]) || " ";
    }
    if (!value2) {
      value2 = (myarr[i-j] && Object.values(myarr[i-j])[0].split(",")[2]) || " ";
    }
    if (value1 && value2) {
      break;
    }
  }
  console.log(date, value1, value2);
  for (var k = 3; k < values.length; k  ) {
    var value = values[k];
    console.log(value);
  }
}

but it doesn't seem to provide the expected output.

Can someone help me with what might be wrong?

CodePudding user response:

Maybe you can use something like this.

const myarr = [
    { "xx": "2023-01-01,,1" },
    { "ss": "2023-01-01,2,1.2" },
    { "dd": "2023-01-01,4," },
    { "rr": "2023-01-01,," },
    { "ff": "2023-01-01,," },
    { "gg": "2023-01-01,," }
]

function fillInBlanks(arr, maxLookBack) {
    return arr.map((obj, index) => {
        const key = Object.keys(obj)[0]
        const value = Object.values(obj)[0]
            .split(",")
            .map((x, n) => {
                if (x === "" && index > 0) {
                    for (let i = index - 1; i >= Math.max(0, index - maxLookBack); --i) {
                        const prev = Object.values(arr[i])[0].split(",")
                        if (prev[n] !== "") return prev[n]
                    }
                } else return x
            })
        return Object.fromEntries([
            [key, value.join(",")]
        ])
    })
}

fillInBlanks(myarr, 2).forEach(x => console.log(x))

CodePudding user response:

Here's my attempt. This will also work with any number of values per row.

const maxAttempts = 2;

myarr.reduce((modifiedAccumulation, currentObject, index) => {
  const [key, csv] = Object.entries(currentObject)[0];
  const splitCsv = csv.split(",");
  const modifiedCsv = splitCsv
    .reduce((fixedArray, currentElement, csvPos) => {
      let numberToUse =
        currentElement === ""
          ? myarr
              .slice(Math.max(index - maxAttempts, 0), index)
              .reduceRight((proposedNum, currentPastObj) => {
                if (proposedNum !== "") return proposedNum;
                let candidate =
                  Object.entries(currentPastObj)[0][1].split(",")[csvPos];
                return candidate !== "" ? candidate : "";
              }, "")
          : currentElement;

      return [...fixedArray, numberToUse];
    }, [])
    .join(",");
  return [...modifiedAccumulation, { [key]: modifiedCsv }];
}, []);


  • Related