Here is the array [2, 44, 7, 38]
. It's the string length of my table cells, so the table width is 100%. Now table will have 4 columns as the same as the length of the array. Now I want to convert this array into width percentage as more big values will get more place in the table.
I need the js method to convert an array that has dynamic length and inside it, dynamic values but it should give % to more which value is big.

- 31
- 4
-
Unless you're using a monospace font, the string char length is not going to be proportional to its rendered length. – Terry Sep 24 '22 at 15:56
-
@Mian person: Why do you need to calculate the column widths? Html tables with some css can provide pretty decent auto-widths (retaining a total table width of 100%). See this [codepen](https://codepen.io/herrstrietzel/pen/yLjPyzj) – herrstrietzel Sep 24 '22 at 16:46
2 Answers
If I understand the question correctly, the aim is to produce an array of widths in units appropriate to a UI (like px) that are proportional to the input string lengths.
The way to do this is to normalize the string lengths -- divide each by the sum of the lengths -- then apply those proportions to the new units.
const array = [2, 44, 7, 38];
const sum = array.reduce((acc, i) => acc+i, 0);
const normalized = array.map(i => i/sum);
// applied to, say, 600 px
const totalWidth = 600;
const widths = normalized.map(n => n*totalWidth);
console.log(widths)
In functional form:
// answer an array of values proportional to lengths summing to totalWidth
function widthsFromLengths(lengths, totalWidth) {
const sum = lengths.reduce((acc, i) => acc+i, 0);
const normalized = lengths.map(i => i/sum);
return normalized.map(n => n*totalWidth);
}
Note that if the goal is to proportionally fit text rendered in a variable width font, the input strings can/should first be converted to widths via an idea like the one given here.

- 62,181
- 10
- 95
- 136
Let us take a look at this snippet
function calculateWidth(arr, container) {
let nodes = container.children;
let sum = arr.reduce(function(a, b) {
return a + b;
}, 0);
if (nodes.length > arr.length) {
alert("Not enough elements in the array");
return;
} else {
for (let i = 0; i < nodes.length; i++) {
nodes[i].style.width = 100 * arr[i] / sum + "%";
}
}
}
const arr = [2, 44, 7, 38];
let container = document.getElementsByClassName("container")[0];
calculateWidth(arr, container);
.container {
width: 100%;
height: 20px;
display: flex;
}
.container * {
height: 100%;
outline: 2px ridge royalblue;
}
<div class="container">
<p>he</p>
<p>i love your help please help kindly</p>
<p>okokokokokokok</p>
<p>i love your help please help kindly</p>
</div>
The magic happens in the function calculateWidth
.
It will receive an array as arr
and a node element that elements inside it would be width-ifying :) as "container".
The nodes
variable would have the elements, that are the children of arr. &
sum` would be, well, sum of the numbers in the arr.
if the size of the arr
is less than nodes', then the operation would be cancelled otherwise, in a for loop, the width of the elements in nodes
would be calculated and assigned.

- 161
- 9