seaman78
seaman78

Reputation: 1

Array of strings of multiple numbers. Math avg

Please kindly help me with the following string/array mess.

The async function returns the following

[ '0 0 0.33 0.019 0 0 0.173 0.009', '0 0.133 0 0 0 0 0 0.05', '0.1 0.11 0.5 0 0 0 0 0.333', 'COMPLETE' ]

how do I find an average of the numbers of each string and how do I push the numbers of each string to its own html table?

I tried some combination of .toString().split() methods and the loops below but didnt get anywhere

const parametersOfCRWs = await getCRWs(idle, "worker:1");
let splits = parametersOfCRWs.toString().split(",");
let arr = "";
let sum = 0;
let count = 0;
for (let i = 0; i < splits.length-1; i++) {
arr = splits[i].split(" ");
for (let j = 0; j < arr.length; j++) {
sum = sum + Number(arr[j]);
console.log(arr[i]);
}
avg = sum / 8;   //always 8 numbers in every string
console.log(avg);

average number turned out to be wrong

Upvotes: 0

Views: 98

Answers (4)

You can do something like: (get your own data first, this data variable is just an example)

let data = [ "0 0 0.33 0.019 0 0 0.173 0.009", "0 0.133 0 0 0 0 0 0.05", "0.1 0.11 0.5 0 0 0 0 0.333", "COMPLETE" ]
data = data.map(e=> {
    if(e !== 'COMPLETE') {
        let average = 0
            e.split(' ').forEach(r => {average +=Number(r)})
        average = average/e.split(' ').length
        return average
    }
    return 'COMPLETE'
})
console.log(data)

output:

[ 0.066375, 0.022875, 0.130375, "COMPLETE" ]

Upvotes: 0

Mushroomator
Mushroomator

Reputation: 9178

This works even if you have unexpected tokens in your input strings. See snippet below.

const input = [
  "0 0 0.33 0.019 0 fssd 0 dfssd 0.173 0.009",
  "0 0.133 0 0 0 0 sdfsd 0 0.05",
  "0.1 0.11 0.5 dsfsd 0 0 dsfsd 0 0 0.333",
  "COMPLETE",
];

const output = input.map((str) => {
  const { sum, count } = str.split(" ").reduce(
    (avg, value) => {
      const possibleFloat = Number.parseFloat(value);
      if (isNaN(possibleFloat)) return avg;
      avg.sum += possibleFloat;
      avg.count++;
      return avg;
    },
    { sum: 0, count: 0 }
  );
  return sum / count;
});

console.log(output);

Upvotes: 1

Nina Scholz
Nina Scholz

Reputation: 386578

You could split the strings, add all values and get the result for mapping.

const
    data = ['0 0 0.33 0.019 0 0 0.173 0.009', '0 0.133 0 0 0 0 0 0.05', '0.1 0.11 0.5 0 0 0 0 0.333', 'COMPLETE'],
    result = data.map(s => s === 'COMPLETE'
        ? s
        : s.split(' ').reduce((s, v) => s + +v, 0) / 8
    );

console.log(result);

Upvotes: 2

mr rogers
mr rogers

Reputation: 3260

The following code will give you a new array which contains the averages of all the numbers in each entry.


const validEntries = parametersOfCRWs.reduce((memo, entry) => {
  const numbers = entry.split(/\s+/);
  if (numbers.length !== 8) {
    // skip this entry (like "COMPLETE")
    return memo;
  }
  memo.push(numbers.map((n) => Number(n)));
  return memo
}, []);

const averages = validEntries.map((numbers) => numbers.reduce((a, b) => a + b));

console.log(validEntries, averages);

This basically assumes that the parametersOfCRWs is an actual javascript array. So instead of toString().split(",") we just use it like an array.

For each entry we split the string by spaces. If it doesn't have 8 entries (like "COMPLETE"), then we skip it.

If it does, we convert each element to a number so that we can compute the average.

Upvotes: 0

Related Questions