I have received result from Raspberry Pi as Text format and I want to use these text to insert into MongoDB as key-pair value or JSON for my Node.js Application. However, I am quite new with JavaScript and trying to figure out the solution. Please help me if you have any suggestion, Thank you very much.
Example:
//Text from Raspberry Pi
1, 2300,450
2, 2200, 920
3, 3400, 440
and I want it to be
[
{
person: 1,
x position: 2300,
y position: 450
},
{
person: 2,
x position: 2200,
y position: 920
},
{
person: 3,
x position: 3400,
y position: 440
}
]
CodePudding user response:
You can first create array from the text by using split
method and then convert the input array to the array of the object
- Split on new line character
/n
to get the lines - Split on the comma and space
,
to get all the elements - Loop over the array and convert array element to object
Code snippet
let input = `1, 2300, 450
2, 2200, 920
3, 3400, 440`;
let linesArr = input.split(/\n/);
let elArray = linesArr.map((line) => line.split(', '))
let result = elArray.map((el) => {
return {
"person": parseInt(el[0]),
"x_position": parseInt(el[1]),
"y_position": parseInt(el[2])
}
})
console.log(result)
CodePudding user response:
You can transform your string into an array, use an array to store the exact name of your keys and then through .reduce create your new array.
const input = '1, 2300, 450, 2, 2200, 920, 3, 3400, 440';
const keys = ['person', 'x position', 'y position'];
let obj = {};
let counter = 0;
const result = input.split(',').reduce((acc, x) => {
obj[keys[counter]] = x.trim();
counter
if (counter % 3 === 0) {
acc.push(obj)
counter = 0;
obj = {};
}
return acc;
}, [])
console.log(result)
CodePudding user response:
Use split and map
let txt = `
1, 2300,450
2, 2200, 920
3, 3400, 440`;
let split = txt.split(/\n/);
let filter = split.filter(e => e != '');
let map = filter.map(function(f1) {
let obj = {}
obj['person'] = parseInt(f1.split(',')[0].trim(), 10);
obj['x position'] = parseInt(f1.split(',')[1].trim(), 10);
obj['y position'] = parseInt(f1.split(',')[2].trim(), 10);
return obj;
});
console.log(map);
CodePudding user response:
const fs = require("fs");
let data = fs.readFileSync("fs.txt", 'utf8');
let splitedData = data.split(",");
let final = [];
let person = splitedData[0];
let length = splitedData.length;
console.log(splitedData);
for(i=1;i<length; i=i 2){
let yposper;
let xposition = splitedData[i];
let yposition;
if(i!=(length-2)){
yposper = splitedData[i 1].split("\r\n");
yposition = yposper[0];
} else{
yposition = splitedData[i 1];
}
final.push({
person: person,
xposition: xposition.trim(),
yposition: yposition.trim()
});
person = i!=(length-2) ? yposper[1] : null;
}
console.log(final);
CodePudding user response:
My own suggestion would be:
// creating a named function, as a constant, since the function isn't
// expected to be modified by code; this function is defined using
// Arrow syntax, and passes in the Event Object - from the (later)
// use of EventTarget.addEventListener() - to the function body:
const getResults = (evt) => {
// here we retrieve the element to which the function was bound
// with EventTarget.addEventListener():
let button = evt.currentTarget,
// from the <button> element we navigate - with Element.closest()
// to the closest ancestor-element that matches the supplied CSS
// selector; note that if no such element is found then this
// will return null. So if you can't be sure the element will
// exist, sanity-check the variable before use:
ancestor = button.closest('li'),
// from the ancestor we retrieve the <textarea> element, using
// Element.querySelector(), which finds the first element
// inside of the ('ancestor', <li>) Element that matches the
// selector; again: if no such element is found, this will
// return null:
textarea = ancestor.querySelector('textarea'),
// this is my habitual practice, but effectively we try to
// retrieve the value property of the <textarea> element, if
// that doesn't have a value, or returns a falsey value,
// we retrieve the text-content instead:
entry = textarea.value || textarea.textContent,
// here we split the value/text-content on new-line characters,
// using String.protoype.split() and passing in a regular
// expression literal (/<regex sequence>/); which returns an
// Array. We then use Array.prototype.reduce() to return a new
// Array based on the passed-in Array:
result = entry.split(/\n/).reduce(
// here we pass in the accumulator ('acc', the Array we're working
// to produce on each iteration through this Array) and the
// Array-entry ('curr'):
(acc, curr) => {
// here we split the current ('curr') Array-value which is a String,
// again using String.prototype.split() and a regular expression-literal;
// this regular expression matches a comma followed by zero-or-more white-
// space characters (tabs, space, etc...); we expect this String to return
// a three part Array and we know the order; so we can use destructuring
// assignment to define person as equal to the first Array-element,
// posX to the second and posY to the third. If there are more
// Array elements returned those will be unallocated:
let [person, posX, posY] = curr.split(/,\s*/);
// I can't remember the term for this, but it's effectively a shorthand;
// but we use Array.prototype.push() to add an Object to the
// accumulator Array; this Object passes in the variables and those variables
// become both the name of the property (so the variable 'person' becomes both
// the property 'person' and sets the value of that property to the value of
// the variable):
acc.push({
person,
posX,
posY,
});
// we return the accumulator to continue working on it in the next iteration:
return acc;
// and here we pass in an empty Array-literal to act as the accumulator:
}, []);
// logging the result to the console:
console.log(result);
},
// here we find all <button> elements with a 'type' attribute equal to 'button', using
// document.querySelectorAll() to obtain a NodeList:
buttons = document.querySelectorAll('button[type=button]');
// here we use NodeList.prototype.forEach() to iterate over the <button> elements:
buttons.forEach(
// passing in a reference to the current Node of the NodeList over which we're iterating
// to the Arrow function-body, and using EventTarget.addEventListener() to bind the
// getResults() function as the event-handler for the 'click' event, this also passes
// the Event Object to the named function:
(btn) => btn.addEventListener('click', getResults)
);
*,
::before,
::after {
box-sizing: border-box;
font-family: sans-serif;
font-size: 16px;
font-weight: 400;
line-height: 1.5;
margin: 0;
padding: 0;
}
ul,
li {
list-style-type: none;
padding: 1em;
}
li {
display: flex;
flex-direction: column;
gap: 0.5em;
justify-content: space-between;
}
textarea {
min-height: 40vmin;
width: 100%;
}
<ul>
<li >
<textarea>1, 2300,450
2, 2200, 920
3, 3400, 440</textarea>
<button type="button">format</button>
</li>
</ul>
This, of course, relies upon the result being returned from the Pi with each entry on a new line; if this can't be guaranteed, or the Pi returns entries in a String without new-lines, the following may be preferred:
// this is much the same as above, except that we have no line-separators (though this
// may not be relevant to your situation):
const getResults = (evt) => {
let button = evt.currentTarget,
ancestor = button.closest('li'),
textarea = ancestor.querySelector('textarea'),
entry = textarea.value || textarea.textContent,
// here we split the retrieved value/text-content of the <textarea> on the ','
// (comma) characters; and then iterate over the returned Array using an
// Arrow function, to trim any leading, and/or trailing, white-space from
// each Array entry:
haystack = entry.split(/,/).map((v) => v.trim()),
// here we use Array.prototype.reduce() to create the Array to return:
result = haystack.reduce(
// we again use the accumulator ('acc'), and the current ('curr') array-value,
// but we also pass in the index of the current Array-element:
(acc, curr, index) => {
// if the remainder left after dividing the current index by 3 is
// exactly 0 (true for 0, 3, 6, 9...):
if (index % 3 === 0) {
// we use destructuring assignment to assign the named
// variables ('person', 'posX', 'posY') to the result of
// calling Array.splice() on a copy of the 'haystack'
// Array (copied using spread syntax ('...') and an Array-literal
// ('[]'); this removes n (here, 3) elements from the copy, starting at
// the Array index 'index', and returns the removed Array elements:
let [person, posX, posY] = [...haystack].splice(index, 3);
// here we - again - push an Object, defined using the same shorthand
// as above, to the accumulator Array:
acc.push({
person,
posX,
posY
});
}
return acc
}, []);
// loggin the result variable:
console.log(result);
},
buttons = document.querySelectorAll('button[type=button]');
buttons.forEach(
(btn) => btn.addEventListener('click', getResults)
);
*,
::before,
::after {
box-sizing: border-box;
font-family: sans-serif;
font-size: 16px;
font-weight: 400;
line-height: 1.5;
margin: 0;
padding: 0;
}
ul,
li {
list-style-type: none;
padding: 1em;
}
li {
display: flex;
flex-direction: column;
gap: 0.5em;
justify-content: space-between;
}
textarea {
min-height: 40vmin;
width: 100%;
}
<ul>
<li >
<textarea>1, 2300,450, 2, 2200, 920,3, 3400, 440</textarea>
<button type="button">format</button>
</li>
</ul>
References: