This question already has answers here:
Convert CSV data into JSON format using Javascript
(7 answers)
Closed 28 days ago.
I like to convert this txt to json file like the format I attached.
here my txt:
`
WarehouseId WarehouseName SKU NUMBER SKU Name rackSection gatewayID tagAddress lightActive caseCount
50 Lakewood 45234 Mountain Dew (20oz) 4 1 1 True 24
50 Lakewood 65197 Dr Pepper (20oz) 5 1 2 True 24
50 Lakewood 45206 Diet Dr Pepper (20oz) 5 1 3 True 24
50 Lakewood 65209 Diet Pepsi (20oz) 6 1 4 True 24
I tried to use data.split(" ") but after that Idk what is the next step and how to make it to json file.
this is the result I like to achieve ( a json file ) :
[
{
"warehouseId" : 50,
"WarehouseName":"Lakewood",
"SKU NUMBER":45234,
"SKU Name":"Mountain Dew (20oz)",
"rackSection":4,
"gatewayID":1,
"tagAddress":1,
"lightActive":"True",
"caseCount":24
},
{
"warehouseId" : 50,
"WarehouseName":"Lakewood",
"SKU NUMBER":65197,
"SKU Name":"Dr Pepper (20oz)",
"rackSection":5,
"gatewayID":1,
"tagAddress":2,
"lightActive":"True",
"caseCount":24
},
{
"warehouseId" : 50,
"WarehouseName":"Lakewood",
"SKU NUMBER":45206,
"SKU Name":"Diet Dr Pepper (20oz)",
"rackSection":5,
"gatewayID":1,
"tagAddress":3,
"lightActive":"True",
"caseCount":24
},
{
"warehouseId" : 50,
"WarehouseName":"Lakewood",
"SKU NUMBER":65209,
"SKU Name":"Diet Pepsi (20oz)",
"rackSection":6,
"gatewayID":1,
"tagAddress":4,
"lightActive":"True",
"caseCount":24
}
]```
Many thanks.
This question will probably be closed as a duplicate, but here is a simple solution:
const lines = file.split('\n');
const headers = lines[0].split('\t');
let data = [];
for(let i = 1; i < lines.length; i++) {
const line = lines[i].split('\t');
const obj = {};
for(let j = 0; j < headers.length; j++) {
obj[headers[j]] = line[j];
}
data.push(obj);
}
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I want to generate an ordered sequence of random numbers and put them in a table (array or object) like below, but I have no idea how to do it:
1
2
3
4
5
6
7
8
9
6
12
35
63
71
8
39
50
78
15
29
43
52
66
85
the result I want can be something like below, I just showed it in a table above to be more readable, as you see each column represented as a sub array below:
[[6,8, ],[12, ,15],[ , ,29],[35,39, ],[ , ,43],[ ,50,52],[63, ,66],[71,78, ],[ , ,85]]
or it can be an object like this, if result is an object each key-value pair represents a column:
{1:[6,8, ],2:[12, ,15],3:[ , ,29],4:[35,39, ],5:[ , ,43],6:[ ,50,52],7:[63, ,66],8:[71,78, ],9:[ , ,85]}
here are the rules:
column 1 must be from 1 to 9, column 2 must be from 10 to 19 ..., col 9 must be from 80 to 90
each column must have at least 1 number
numbers in each column must be ordered. but randomly placed.
Update
till now I create a sequence of ordered random numbers using this:
const randomNumber = (min, max) => {
return Math.floor(Math.random() * (max - min + 1)) + min;
};
const createSequence = () => {
const sequence = [];
for (let row = 0; row < 9; row++) {
let column = [];
while (true) {
let random;
if (row == 0) {
random = randomNumber(1, 9);
} else {
random = randomNumber(row * 10, row * 10 + 9);
}
if (!column.includes(random)) {
column.push(random);
}
if (column.length >= 3) {
column = column.sort();
break;
}
}
sequence.push(column);
}
console.log(sequence);
return sequence;
};
createSequence()
using above code I get something like this:
[
[
7,
8,
9
],
[
12,
16,
19
],
[
20,
23,
24
],
[
33,
35,
36
],
[
44,
46,
47
],
[
51,
56,
58
],
[
60,
66,
68
],
[
70,
73,
77
],
[
80,
84,
86
]
]
now I have to remove numbers randomly from the array, to achieve the goal, but I don't know how? any idea or solution (or a completely different approach) is appreciated.
thank you all.
Part of solving a problem like this is figuring out if there's a different representation that would make it easier to solve. Tables are usually arranged as a series of rows. However, treating the table as a series of columns makes solving this easier.
An additional, tricky issue is that the column ranges aren't same for all columns. Most columns have a range of 10 but the first column has a range of 9 and the last column has a range of 11.
The solution here generates values for all cells and then eliminates ~half of them, leaving at least one in each column.
const randRng = (min, max) => Math.floor(Math.random() * (max + 1 - min) + min);
const generateData = (rows, cols, p = 0.5) => {
const data = [];
for(let c = 0; c < cols; c++) {
const min = c == 0 ? 1 : c * 10;
const max = c == 0 ? 9 : c == cols - 1 ? min + 10 : min + 9;
// fill all the cells with unique values
const set = new Set();
do {
set.add(randRng(min, max));
} while(set.size < rows);
const sorted = Array.from(set).sort();
// filter out some of the cells, keep at least one
const keep = Math.floor(Math.random() * rows);
const values = sorted.map(
(v, i) => (keep == i || Math.random() < p ? v : null)
);
data.push(values);
}
return data;
};
const tableFromData = (data) => {
const table = [];
// add table header
table.push('<thead><tr>');
for(let c = 1; c <= data.length; c++) {
table.push(`<th>${c}</th>`);
}
table.push('</tr></thead>');
// swap cols/rows and convert to html
for(let r = 0; r < data[0].length; r++) {
table.push('<tr>');
for(let c = 0; c < data.length; c++) {
table.push(`<td>${ data[c][r] ?? " " }</td>`);
}
table.push('</tr>');
}
return table.join('');
};
const data = generateData(3, 9);
const table = tableFromData(data);
document.querySelector('table').insertAdjacentHTML('beforeend', table);
table {
border-collapse: collapse;
}
table, th, td {
border: 1px solid black;
}
th, td {
width: 3em;
text-align: center;
}
<table></table>
Note that, since we generate values for all cells and then filter them, distribution is such that first rows will tend to have values towards the beginning of the range, progressing to the last rows having values towards the end of the range.
There seems many different ways to approach this, but one way would be to create random numbers and insert them into a list, one at a time, where they would be in order.
To have the 2-d portion of the table it would just be another step while inserting. Sort on the 10's place, then in that index of the array you could insert based on the 1's place.
I have an array of objects with a property called size. See example array below.
var products = [{"name":"product 1", "size":25},{"name":"product 2", "size":15},{"name":"product 3", "size":3}]
I'm looking for an algorithm that returns the optimal amount of products to "fill" a certain size.
By optimal I mean it returns the lowest amount of products with the least amount of leftover size.
For example, let's say the target size is 72. I would like to return the following products:
2 x product 1
1 x product 2
3 x product 3
The array is ordered from highest to lowest size.
I have tried the following (this is a simplified version of my code).
For now I'm simply console logging the results.
var totalSize = 72
products.forEach(function (arrayItem) {
if(multiplierSize / arrayItem.size >= 1) {
var minTimes = Math.floor(totalSize / arrayItem.size);
var minAmount = (minTimes * arrayItem.size);
multiplierSize -= minAmount;
console.log(arrayItem.name + " x " + minTimes)
}
});
The above example won't properly fill out the total size and will result in the following:
2 x product 1
1 x product 2
2 x product 3
Any help that could point me in the right direction would be greatly appreciated.
I'm assuming you are not required to include at least one of every product. If that should be the case then the below solution won't work. I'm also not sure what you want the end result to look like but basically you can use a recursive function that checks each products and it's size, sees how many times it goes into the passed total and then creates a newTotal based on that. As you iterate through the products, determine the amount of times a product can go into the newTotal, store the amount and he product name in an object and push it into calcSizes. Then check if the newTotal is equal to the passed total. If so, log calcSizes, otherwise, reorder the products so the second one becomes the first one and the first one is pushed to the back. Then call the evalProducts and pass total and the the new products array.
Note: I use Math.trunc instead of Math.round to be conservative in calculating the amount since I'm assuming negative amounts are not permitted. For example, using Math.round when passing the original number 72, you would end up with the below result.
{
"name": "product 1",
"amount": 3
},
{
"name": "product 2",
"amount": 0
},
{
"name": "product 3",
"amount": -1
}
]
I tried the function with a few numbers in addition to the original 72. I am not sure if this is the most optimal solution as I do not have a math background but from a JS perspective and talking in terms of time complexity I think it is reasonable.
var products = [{
"name": "product 1",
"size": 25
}, {
"name": "product 2",
"size": 15
}, {
"name": "product 3",
"size": 3
}]
var potentialCalcSizes = {}
const evalProducts = (total, newProducts) => {
var calcSizes = []
var newTotal = 0
var prods = newProducts ? newProducts.slice() : products.slice();
//reset potentialCalcSizes
potentialCalcSizes = newProducts ? potentialCalcSizes : {}
prods.forEach(function(arrayItem) {
var calcSize = {}
var calcNum
if (newTotal === 0) {
calcNum = Math.trunc(total / arrayItem.size)
calcSize['name'] = arrayItem.name
calcSize['amount'] = calcNum
newTotal = calcNum * arrayItem.size
} else {
calcNum = Math.trunc((total - newTotal) / arrayItem.size)
calcSize['name'] = arrayItem.name
calcSize['amount'] = calcNum
newTotal += calcNum * arrayItem.size
}
calcSizes.push(calcSize)
});
if (total === newTotal) {
return calcSizes
} else {
potentialCalcSizes[newTotal] = calcSizes
var first = prods[0];
var second = prods[1];
prods.shift();
prods.push(first)
if (products[0].name === prods[0].name) {
return findNextClosest(potentialCalcSizes, total)
} else {
return evalProducts(total, prods)
}
}
}
const findNextClosest = (obj, total) =>{
var closestToTotal = Infinity;
Object.keys(potentialCalcSizes).forEach(x=>{
if (Math.abs(total-parseInt(x)) < closestToTotal){
closestToTotal = parseInt(x)
}
})
return obj[closestToTotal]
}
console.log('72')
console.log(evalProducts(72))
console.log('78')
console.log(evalProducts(78))
console.log('82')
console.log(evalProducts(82))
console.log('75')
console.log(evalProducts(75))
You could take a brute force approach and collect all possible combinations and filter the result by taking only the ones with minimum counts and totals.
The result set contains arrays with
count of items at the same index,
total of sizes,
counts of all items.
Example of filtering of raw result:
indices totals counts comment
---------- ------ ------ ---------------------------------------
raw 3 75 3
2 2 80 4
2 1 3 74 6
2 8 74 10
1 4 85 5
1 3 1 73 5
1 2 6 73 9
1 1 11 73 13
1 16 73 17
5 75 5
4 4 72 8
3 9 72 12
2 14 72 16
1 19 72 20
24 72 24
1st 3 75 3 get the smallest of every group
filter 2 2 80 4
2 1 3 74 6
1 3 1 73 5
4 4 72 8
2nd 3 75 3 is better than 2 2 80 4
filter 1 3 1 73 5 is better than 2 1 3 74 6
4 4 72 8 has no comparable value
function getParts(array, target) {
function iter(index, temp, total, push) {
if (push && total >= target) {
var count = temp.reduce((a, b) => a + b);
result.push([temp.join(' '), total, count]);
if (!totals.has(total) || count < totals.get(total)) totals.set(total, count);
if (!counts.has(count) || total < counts.get(count)) counts.set(count, total);
return;
}
if (index >= array.length) return;
var l = Math.ceil((target - total) / array[index].size);
do iter(index + 1, [...temp, l], total + l * array[index].size, true);
while (--l)
iter(index + 1, temp, total, false);
}
var result = [],
totals = new Map,
counts = new Map;
iter(0, [], 0);
return result
.filter(([, total, count]) =>
totals.get(total) === count &&
counts.get(count) === total
)
.filter(([, total, count], _, array) =>
array.some(a => total < a[1] && count < a[2]) ||
!array.some(a => total > a[1] && count > a[2])
);
}
var products = [{ "name": "product 1", "size": 25 }, { "name": "product 2", "size": 15 }, { "name": "product 3", "size": 3 }],
target = 72,
result = getParts(products, target);
result.forEach(a => console.log(a.join(' | ')));
You could try a linear optimizsation lib for js, e.g. https://www.npmjs.com/package/simple-simplex.
Just define your optimization problem like a Knapsack problem
Your only constraints would be
25a + 15b + 3c <= 72
and your objective to minimize a + b +c
I think the documentation of simple-simplex will explain everythin you need.
This question already has answers here:
JavaScript adding a string to a number
(8 answers)
Closed 3 years ago.
var x = 10 + Number("1"+"6");
console.log(x);
returns: 26
var y = 10 + 1 + 6;
console.log(y);
returns: 17
You're adding two strings together inside Number(...):
"1" + "6" = "16"
So the line basically comes down to:
var x = 10 + Number( "16" )
> 26
In your first example Number("1"+"6"), "1" and "6" evaluate as strings (because of the quotes). When JS adds strings it concatenates them, so "1" + "6" becomes "16" the same way that "Hello " + "world" becomes "Hello world".
In your second example all of the numbers are treated as numbers, so they are added as you expect.
"1"+"6" = "16" : concatenation fo 2 strings
Number("1"+"6") = Number("16") = 16
10 + 16 = 26
let x = 10 + Number("1") + Number("6"); //for x to equal 17
here a function i use to sum numbers regardless of arguments are numbers or strings (return null if any of the arguments is not a number)
function sumNumbers(){
let result = 0;
for(arg of arguments){
let nArg = Number(arg);
if(isNaN(nArg)){
return null;
};
result+=nArg;
}
return result;
}
This question already has answers here:
Javascript number comparison fails
(2 answers)
Closed 4 years ago.
Challenge:
You are given a string of space-separated numbers and have to return the highest and lowest number.
Problem:
Expected: '542 -214', instead got: '6 -214'
I can't understand why the system thinks 6 is higher than 542. The program works fine when the 6 is removed.
Code:
function highAndLow(numbers){
numbers = numbers.split(" ");
var biggest = numbers[0];
for (i = 0; i < numbers.length; i++) {
if (numbers[i] > biggest) {
biggest = numbers[i];
}
}
var smallest = numbers[0];
for (i = 0; i < numbers.length; i++) {
if (numbers[i] < smallest) {
smallest = numbers[i];
}
}
return biggest + " " + smallest;
}
console.log(highAndLow("4 5 29 54 4 0 -214 542 -64 1 -3 6 -6"));
JSBin Link
This is because it's comparing the numbers as strings instead of as numbers. You'll want to convert them to numbers using the Number() function to convert them to numbers before you compare them, for example:
biggest = Number(numbers[0]);
in the code below I want to print the values of "years_of_experience" which is less than 34 and birthplace which is equal to "texas". But I'm not getting how to write the statement correctly
var employees = [
{
name1:'jacob',
age2 : 23,
date_of_join : 23/03/2013,
years_of_experience : 12,
birth_place: "virginia"
},
{
name2:'sheldon',
age2 : 34,
date_of_join :2/03/2013,
years_of_experience : 15,
birth_place: "lisbon"
},
{
name3:'johnny',
age3 : 25,
date_of_join :29/03/2013,
years_of_experience : 13,
birth_place: "texas"
}];
employees.forEach(function(a) {
console.log(a);
});
for(var i = 0;i <= employees.length;i++)
{
if(employees[i]!= -1)
{
console.log("gotcha");
if(employees.hasOwnProperty === years_of_experience) < 34 || (employees.hasOwnProperty(birth_place) === "teaxs")
{
//here i want to print the values of
// "years_of_experience" which is less than 34 and birthplace which is equal to
// "texas".But i'm not getting how to write the statement for that become m new to
// javascript and even m not sure i've written the conditional statement right,
// please correct it and help me..
}
}
}
Try this
if(employees[i].years_of_experience < 34 || employees[i].birth_place === "teaxs")
Like this
var years = employees[i]["years_of_experience"];
var POB = employees[i]["birth_place"];
if (years < 34 || POB === "texas") {
document.getElementById("idOfSomeTag").innerHTML = "Years:" years +", POB"+POB;
// or console.log("years",years,"Pob",POB);
}
Firstly, you misspelled 'texas'
hasOwnProperty() is a method, not a property and also it doesn't pull the value from a property, it simply returns a boolean of whether it has or does not have that property.
You may want something like the following
for (var i = 0; i < employees.length; i++) {
if (employees[i].hasOwnProperty("years_of_experience") && employees[i].hasOwnProperty("birth_place")) {
if (employees[i].years_of_experience < 34 || employees[i].birth_place === "texas") {
console.log("Year of Experience: \n" + employees[i].years_of_experience + "\nBirth Place: " + employees[i].birth_place);
}
}
}
jsFiddle : Check your console.
You should also change your "date_of_join" into a string if that's the way you want to store dates. Right now you are getting a very obscure decimal value.
var employees = [{
...
date_of_join: "23 / 03 / 2013",
...
}, {
...
date_of_join: "2 / 03 / 2013",
...
}, {
...
date_of_join: "29 / 03 / 2013",
...
}];