split function is duplicating values - javascript

I am trying to split a string with split() and for some reason, it is giving me duplicate values this is driving me mad can someone please assist me
The string is a comma separated response from a database here is the echo
echo $Title1 . ',' . $link. ','.$value. ','.'number'.','.'$' .',';
Here is my code:
function displayMatches(response2){
var str = response2;
var str_array = response2.split(',');
}
This is the console log from str_array
0: "Butter cauliflower & paneer"
1: "https://link1.com"
2: "4"
3: "friends5"
4: "$"
5: "Butter cauliflower & paneer"
6: "https://link1.com"
7: "4"
8: "friends5"
9: "$"
10: "Butter cauliflower and coconut sambal"
11: "https://link2.com"
12: "3"
13: "friends5"
14: "$"
15: "Butter cauliflower and coconut sambal"
16: "https://link2.com"
17: "3"
18: "friends5"
19: "$"
Here is the value of response2
Butter cauliflower & paneer,https://link1.com,4,friends5,$,Butter cauliflower & paneer,https://link2.com,4,friends5,$,Butter cauliflower and coconut sambal,https://link3.com,3,friends5,$,Butter cauliflower and coconut sambal,https://link4.com,3,friends5,$,Creamy vegetarian pumpkin curry,https://link5.com,5,friends5,$,
Why is `split()` doing this?

This one had also driven me mad.
Try using this Inside the function
let endArray = new Set([]);
var str_array = response2.split(',');
for(var i = 0;i < str_array.length - 1;i++){
endArray.add(str_array[i]);
}
console.log(endArray)
Also, It would be easier if you would have added the string that you are splitting, This will help more viewers find better options and in less time.
If this didn't work get back to me on this answer as a comment

Related

JavaScript heap out of memory issue on comparing elements in large for loops

I have huge JSON file to process which holds around 15,00,000 JSON objects. I am performing some searching operation where I am using two for loops under which I am comparing object values.
Below is an example:
const data = [
{
"slug": "vertical-lift-module-market",
"id": 68055,
"related_reports_updated": {
"sub_categories": [
{
"slug": "audience-analytics-market",
"id": 66684,
"short_title": "Audience Analytics Market"
},
{
"slug": "mobile-wallet-market",
"id": 68830,
"short_title": "Mobile Wallet Market"
}
}
},
{
"slug": "united-states-real-estate-services---growth-trends-and-forecast-2022-- -2027",
"id": 68056,
"related_reports_updated": {
"sub_categories": [
{
"slug": "canada-real-estate-services-market---growth-trends-and-forecast-2020---2025",
"id": 68051,
"short_title": "Canada Real Estate Services Market"
},
{
"slug": "germany-real-estate-services-market--growth-trends-and-forecast-2020---2025",
"id": 68054,
"short_title": "Germany Real Estate Services Market"
},
}
},
{
...
}
]
//This data holds 15,00,000 JSON objects
What I am trying to do is comparing slug of one object with slug available in sub_categories array of other objects. If it's present then create one object and push it into the result array and send that result array.
const result = [];
for(var i=0;i<data.length;i++) {
for(var j=0;j<data.length;j++) {
//Comparing operation
}
}
console.log(result);
But after running sometime its giving me this error:
[41955:0x523ce90] 162238 ms: Mark-sweep (reduce) 4096.9 (4102.7) -> 4096.9 (4104.7)
MB, 3481.7 / 0.4 ms (average mu = 0.092, current mu = 0.000) allocation failure scavenge might not succeed
<--- JS stacktrace --->
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
1: 0xa3ac10 node::Abort() [node]
2: 0x970199 node::FatalError(char const*, char const*) [node]
3: 0xbba58e v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool)
[node]
4: 0xbba907 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char
const*, bool) [node]
5: 0xd76b25 [node]
6: 0xd776af [node]
7: 0xd854eb v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace,
v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [node]
8: 0xd890ac v8::internal::Heap::AllocateRawWithRetryOrFailSlowPath(int,
v8::internal::AllocationType, v8::internal::AllocationOrigin,
v8::internal::AllocationAlignment) [node]
9: 0xd5778b v8::internal::Factory::NewFillerObject(int, bool,
v8::internal::AllocationType, v8::internal::AllocationOrigin) [node]
10: 0x109fd4f v8::internal::Runtime_AllocateInYoungGeneration(int, unsigned long*,
v8::internal::Isolate*) [node]
11: 0x1448f59 [node]
Aborted (core dumped)
To get rid of this error I even tried node --max-old-space-size=4096 index.js for maximizing memory for node processes.
But I am still getting the same issue. Is there any other way to resolve this issue and get the desired result?
Let's assume that any element have word and number.
double precision 64-bit number in js takes 8 bytes*
word with 5 letters is around 10 bytes**
If single element have 18 bytes then
1.5e6 elements is 2.7e7 bytes = 27 MB
Independently from code:
const obj = {};
if(data[i].name == data[j].name) {
obj.name = data[i].name;
}
you pushing to result array in double loop. Any of these loops goes through 1.5e6 elements so summary you are going to add to result a lot elements, in this case: 1.5e6 * 1.5e6 = 2.25e12.
Now let's compute size of result
2.25e12 * (8 bytes + 10 bytes) = 4.05e13 bytes
We know that
1 gigabyte = 1 000 000 000 bytes = 1e9 bytes
1 terabyte = 1e12 bytes
So in your case you need 40 terabytes to save your result.
Definitely you have to rethink algorithm that you want to implement.
*each number actually takes up an average of 9.7 bytes. source
**we can assume 2 bytes per character for but it can be 5 or more bytes source
If you use a less complex algorithm that does not add duplicate values, it will push much lower number of elements into result array.
let dictionary = {};
// O(n) to build dictionary of all parent slugs
for(let i=0;i<n;i++)
{
dictionary[data[i].slug]=1; // hashing
}
// O(n*k) to check dictionary instead of doing O(n*n*k) for brute-force
for(let i=0;i<n;i++)
for(let j=0;j<data[i].sub_cat.length;j++)
{
// O(1)
if(data[i].sub_cat[j].slug in dictionary)
dictionary[data[i].sub_cat[j].slug]++; // 2 => will go to result
}
// add to result O(n)
for (const [key, value] of Object.entries(dictionary)) {
if(value==2)
result.push(key);
}
Since it also compares to itself, like element 5 vs element 5, it may still duplicate as in comparison but not as result item. So you may need to add an extra comparison for that depending on required algorithm.

Onclick event not working as expected. Any idea why?

I am working on a very simple quiz javascript project, with a score and a start button, that generates questions when it gets clicked. I started work in the JS code by adding an onclick event listener, but it is not working as expected. Here is the code snippet that is supposed to be working but doesn't work, with a few comments. Keep in mind that I am very inexperienced in Javascript, so I may have misused some JS methods.
function rng() {
return Math.floor(Math.random * 10)
}
let stbt = document.getElementById("start")
stbt.addEventListener("click", function() {
stbt.remove //should remove the start button when it gets clicked.
let q = document.createElement("p") //created an html paragraph.
switch(rng()) {
case 1:
let qc = document.createTextNode("What is the capital of Chile?")
q.appendChild(qc) /*this should theoretically insert text into the html paragraph that gets created when the start button gets clicked,
the switch statement that is switching the simple rng function should make it so that questions get generated randomly.*/
break;
case 2:
let qc = document.createTextNode("What is the highest mountain in Britain?")
q.appendChild(qc)
break;
case 3:
let qc = document.createTextNode("What is the smallest country in the world?")
q.appendChild(qc)
break;
case 4:
let qc = document.createTextNode("Alberta is a province of which country?")
q.appendChild(qc)
break;
case 5:
let qc = document.createTextNode("How many countries still have the shilling as currency?")
q.appendChild(qc)
break;
case 6:
let qc = document.createTextNode("Which is the only vowel not used as the first letter in a US State?")
q.appendChild(qc)
break;
case 7:
let qc = document.createTextNode("What is the largest country in the world?")
q.appendChild(qc)
break;
case 8:
let qc = document.createTextNode("Where would you find the River Thames?")
q.appendChild(qc)
break;
case 9:
let qc = document.createTextNode("What is the hottest continent on Earth?")
q.appendChild(qc)
break;
case 0:
let qc = document.createTextNode("What is the longest river in the world?")
q.appendChild(qc)
break;
}
})
It is not the listener at fault here, but a number of small errors that are causing your code not to work.
You are not calling two functions: Math.random should be Math.random(), and stbt.remove should be stbt.remove().
Because of the way you have written your switch your qc variable is scoped across all your case statements, so you can't declare it again. You can fix this by either declaring it outside of the switch and assigning it in the case statements, or using braces to scope the variable to each case.
let qc; //<--- declare qc;
switch (rng()) {
case 1:
qc = document.createTextNode("What is the capital of Chile?")
...
break;
case 2:
qc = document.createTextNode("What is the highest mountain in Britain?")
...
or
switch (rng()) {
case 1: { //<--- braces to scope variable declaration
let qc = document.createTextNode("What is the capital of Chile?")
...
break;
}
case 2: {
let qc = document.createTextNode("What is the highest mountain in Britain?")
...
break;
}
case 3: {
...
Lastly, you never append your <p> element to the DOM. You'll need to either query an element to append to, or as in the example below, append directly to the document.body
The switch statement tends to be quite verbose and so it helps to avoid duplication as much as possible. Instead of appending the new text node within each case you can instead move it after the switch and call it just once.
stbt.addEventListener("click", function () {
...
let qc;
switch (rng()) {
case 1:
...
}
// Avoid duplication by appending once at the end
q.appendChild(qc)
document.body.appendChild(q) //<--- append <p> to DOM
});
function rng() {
return Math.floor(Math.random() * 10); //<--- parentheses needed to call function;
}
const stbt = document.getElementById("start");
stbt.addEventListener("click", function () {
stbt.remove(); //<--- parentheses needed to call function;
let q = document.createElement("p");
let qc; //<--- declare qc;
switch (rng()) {
case 1: {
let qc = document.createTextNode("What is the capital of Chile?")
break;
}
case 2:
qc = document.createTextNode("What is the highest mountain in Britain?")
break;
case 3:
qc = document.createTextNode("What is the smallest country in the world?")
break;
case 4:
qc = document.createTextNode("Alberta is a province of which country?")
break;
case 5:
qc = document.createTextNode("How many countries still have the shilling as currency?")
q.appendChild(qc)
break;
case 6:
qc = document.createTextNode("Which is the only vowel not used as the first letter in a US State?")
break;
case 7:
qc = document.createTextNode("What is the largest country in the world?")
break;
case 8:
qc = document.createTextNode("Where would you find the River Thames?")
q.appendChild(qc)
break;
case 9:
qc = document.createTextNode("What is the hottest continent on Earth?")
break;
case 0:
qc = document.createTextNode("What is the longest river in the world?")
break;
}
// Avoid duplication by appending once at the end
q.appendChild(qc)
document.body.appendChild(q) //<--- append <p> to the DOM
});
<button type="button" id='start'>Start</button>
Making it more general
Using a switch can be very clear in showing what is happening, but it does lead to a lot of duplication. If you wanted to add a question you would need to add a whole new case statement as well as change the constant within your rng() function. To avoid this you might want to think about other structures that might serve your purpose.
Here is an example using an Array to store the questions which is accessed by index using the returned value from the rng() (which has been changed to accept a max value). With this structure, adding a question is simply a matter of adding to the array, the rest takes care of itself.
function rng(max) {
return Math.floor(Math.random() * max)
}
const questions = [
"What is the capital of Chile?",
"What is the highest mountain in Britain?",
"What is the smallest country in the world?",
"Alberta is a province of which country?",
"How many countries still have the shilling as currency?",
"Which is the only vowel not used as the first letter in a US State?",
"What is the largest country in the world?",
"Where would you find the River Thames?",
"What is the hottest continent on Earth?",
"What is the longest river in the world?",
]
const stbt = document.getElementById("start")
const div = document.getElementById("questions")
stbt.addEventListener("click", function () {
// pass the length of the questions array as the max value for the rng()
const questionIndex = rng(questions.length);
const question = questions[questionIndex];
stbt.remove();
const q = document.createElement("p");
const qc = document.createTextNode(question)
q.appendChild(qc)
div.appendChild(q)
});
<button type="button" id='start'>Start</button>
<div id='questions'></div>

Wierd Error while working with unlimited argument function Node JS

//##// Function Zone //##//
function out(type, ...strings) {
var str = strings.join(' ');
switch (type) {
case "log":
console.log("\x1b[37m", '[LOG]\t', str, "\x1b[0m");
break;
case "error":
console.log("\x1b[31m",'[ERROR]\t', str, "\x1b[0m");
break;
case "info":
console.log("\x1b[36m", '[INFO]\t', str, "\x1b[0m");
break;
default:
throw new Error('Bad output type');
}
}
When I start the program it crashes with this error:
FATAL ERROR: Error::New napi_get_last_error_info<br/>
1: 00007FF6F206CF2F napi_wrap+112799<br/>
2: 00007FF6F200CF26 v8::base::CPU::has_sse+55702<br/>
3: 00007FF6F200DDB3 v8::base::CPU::has_sse+59427<br/>
4: 00007FF6F200D509 v8::base::CPU::has_sse+57209<br/>
5: 00007FF6F2032410 napi_fatal_error+160<br/>
6: 00007FFC74541DA3 <br/>
7: 00007FFC74541CF7 <br/>
8: 00007FFC7454CB69 <br/>
9: 00007FF6F203032C node_module_register+1548<br/>
10: 00007FF6F20BD340 uv_timer_stop+560<br/>
11: 00007FF6F20BD417 uv_timer_stop+775<br/>
12: 00007FF6F20B9ECB uv_async_send+331<br/>
13: 00007FF6F20B966C uv_loop_init+1212<br/>
14: 00007FF6F20B9834 uv_run+244<br/>
15: 00007FF6F1FC9681 v8::internal::interpreter::BytecodeArrayWriter::source_position_table_builder+31713<br/>
16: 00007FF6F2036223 node::Start+275<br/>
17: 00007FF6F1EB6A9C RC4_options+340380<br/>
18: 00007FF6F2D2F3F8 v8::internal::SetupIsolateDelegate::SetupHeap+1300536<br/>
19: 00007FFCB7CA7034 BaseThreadInitThunk+20<br/>
20: 00007FFCB7DDCEC1 RtlUserThreadStart+33<br/>
Any Idea?
Thank you for helping me!
I finally found the problem, I forgot to modify a function in my code, the error is because of that. I called the method info() that is a standard node.js method an that caused the error.
Thank you anyway :D

json object deserialize issue typescript

As part of my project, I need to write some model data to JSON object and download it to file.
then I need to load that file and deserialize the JSON to model object.
That part is not working
demo project
https://stackblitz.com/edit/angular-wpg5gx
for repro, click on the export button you will get JSON file downloaded and try to import the exported file
expected
{"name":"usa","orgAddress1":"123 broadway","orgAddress2":"2D","city":"new york","system":[{"name":"sap"},{"name":"sap"},{"name":"sap"},{"name":"sap"},{"name":"sap"},{"name":"sap"},{"name":"sap"},{"name":"sap"},{"name":"sap"},{"name":"sap"}]}
actual result:
Partner {0: "{", 1: """, 2: "n", 3: "a"…}
0: "{"
1: """
10: "s"
100: "a"
101: "p"
102: """
103: "}"
104: ","
105: "{"
106: """
107: "n"
108: "a"
109: "m"
11: "a"
110: "e"
...................
Update your conversions to the following
let json = fileReader.result.toString();
let obj = JSON.parse(json);
var convert = Object.assign(new Partner(), obj);
That should get you what you're looking for.
You are calling JSON.stringify() on a string before parsing it. If you remove your JSON.stringify() call, it will work as expected.
let object = JSON.parse(fileReader.result as string);

How to fetch Digits from a String in javascript?

I have a following string in javascript:
var xyz= "M429,100L504.5,100L504.5,106L580,106L570,98M580,106L570,114";
I want to fetch the numbers and store it in an array.
I tried following code:
var x=xyz.match(/\d+/g);
And I got the following output:
0: "429"
1: "100"
2: "504"
3: "5"
4: "100"
5: "504"
6: "5"
7: "106"
8: "580"
9: "106"
10: "570"
11: "98"
12: "580"
13: "106"
14: "570"
15: "114"
As you can see the floating point values such as 504.5 has come up seperately.
How can I fetch this properly?
You can simply change your regex to this one :
var x=xyz.match(/[0-9.]+/g);
It will allow you to capture the number and the float as well.
=> http://www.regexr.com/3b46a
You can change your regEx to this to get floating point values also
var x = xyz.match(/\d+\.*\d/g)
Try this one.
var x=xyz.match(/\d+(\.\d+)?/g);

Categories

Resources