Construct an 2D array of contiguous elements comparing master and incident arrays
up vote
2
down vote
favorite
Requirement:
Based on mainArray
which contains the master list of items, and compArray
which has items of interest; construct a 2 dimensional third array that contains the array of contiguous elements.
The purpose of this requirement is for plotting poly-line on map wherever an incident occurred in contiguous manner, plotted using the finalArray
of locations.
Example:
const mainArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
const compArray = [1, 2, 3, 6, 7, 11, 12, 13, 15];
// produces finalArray
[[ 1, 2, 3 ],[ 6, 7 ],[ 11, 12, 13 ],[ 15 ]]
My current solution:
console.clear();
const mainArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
const compArray = [1, 2, 3, 6, 7, 11, 12, 13, 15];
let compArrayIndex = 0;
let finalArray = ;
let currentArray = null;
for (let i = 0; i < mainArray.length; i++) {
const e = mainArray[i];
if (e === compArray[compArrayIndex]) {
if (!currentArray) {
currentArray = ;
}
currentArray.push(e);
compArrayIndex++;
} else {
if (currentArray) {
finalArray.push([...currentArray]);
currentArray = null;
}
}
}
if (currentArray) {
finalArray.push([...currentArray]);
currentArray = null;
}
console.log(mainArray);
console.log(compArray);
console.log('finl arr:');
for (let i = 0; i < finalArray.length; i++) {
const e = finalArray[i];
console.log(e);
}
javascript
New contributor
add a comment |
up vote
2
down vote
favorite
Requirement:
Based on mainArray
which contains the master list of items, and compArray
which has items of interest; construct a 2 dimensional third array that contains the array of contiguous elements.
The purpose of this requirement is for plotting poly-line on map wherever an incident occurred in contiguous manner, plotted using the finalArray
of locations.
Example:
const mainArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
const compArray = [1, 2, 3, 6, 7, 11, 12, 13, 15];
// produces finalArray
[[ 1, 2, 3 ],[ 6, 7 ],[ 11, 12, 13 ],[ 15 ]]
My current solution:
console.clear();
const mainArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
const compArray = [1, 2, 3, 6, 7, 11, 12, 13, 15];
let compArrayIndex = 0;
let finalArray = ;
let currentArray = null;
for (let i = 0; i < mainArray.length; i++) {
const e = mainArray[i];
if (e === compArray[compArrayIndex]) {
if (!currentArray) {
currentArray = ;
}
currentArray.push(e);
compArrayIndex++;
} else {
if (currentArray) {
finalArray.push([...currentArray]);
currentArray = null;
}
}
}
if (currentArray) {
finalArray.push([...currentArray]);
currentArray = null;
}
console.log(mainArray);
console.log(compArray);
console.log('finl arr:');
for (let i = 0; i < finalArray.length; i++) {
const e = finalArray[i];
console.log(e);
}
javascript
New contributor
1
Why does this question have close votes? The problem is explained, there's an example and the code is there and seems to be working.
– IEatBagels
16 hours ago
add a comment |
up vote
2
down vote
favorite
up vote
2
down vote
favorite
Requirement:
Based on mainArray
which contains the master list of items, and compArray
which has items of interest; construct a 2 dimensional third array that contains the array of contiguous elements.
The purpose of this requirement is for plotting poly-line on map wherever an incident occurred in contiguous manner, plotted using the finalArray
of locations.
Example:
const mainArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
const compArray = [1, 2, 3, 6, 7, 11, 12, 13, 15];
// produces finalArray
[[ 1, 2, 3 ],[ 6, 7 ],[ 11, 12, 13 ],[ 15 ]]
My current solution:
console.clear();
const mainArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
const compArray = [1, 2, 3, 6, 7, 11, 12, 13, 15];
let compArrayIndex = 0;
let finalArray = ;
let currentArray = null;
for (let i = 0; i < mainArray.length; i++) {
const e = mainArray[i];
if (e === compArray[compArrayIndex]) {
if (!currentArray) {
currentArray = ;
}
currentArray.push(e);
compArrayIndex++;
} else {
if (currentArray) {
finalArray.push([...currentArray]);
currentArray = null;
}
}
}
if (currentArray) {
finalArray.push([...currentArray]);
currentArray = null;
}
console.log(mainArray);
console.log(compArray);
console.log('finl arr:');
for (let i = 0; i < finalArray.length; i++) {
const e = finalArray[i];
console.log(e);
}
javascript
New contributor
Requirement:
Based on mainArray
which contains the master list of items, and compArray
which has items of interest; construct a 2 dimensional third array that contains the array of contiguous elements.
The purpose of this requirement is for plotting poly-line on map wherever an incident occurred in contiguous manner, plotted using the finalArray
of locations.
Example:
const mainArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
const compArray = [1, 2, 3, 6, 7, 11, 12, 13, 15];
// produces finalArray
[[ 1, 2, 3 ],[ 6, 7 ],[ 11, 12, 13 ],[ 15 ]]
My current solution:
console.clear();
const mainArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
const compArray = [1, 2, 3, 6, 7, 11, 12, 13, 15];
let compArrayIndex = 0;
let finalArray = ;
let currentArray = null;
for (let i = 0; i < mainArray.length; i++) {
const e = mainArray[i];
if (e === compArray[compArrayIndex]) {
if (!currentArray) {
currentArray = ;
}
currentArray.push(e);
compArrayIndex++;
} else {
if (currentArray) {
finalArray.push([...currentArray]);
currentArray = null;
}
}
}
if (currentArray) {
finalArray.push([...currentArray]);
currentArray = null;
}
console.log(mainArray);
console.log(compArray);
console.log('finl arr:');
for (let i = 0; i < finalArray.length; i++) {
const e = finalArray[i];
console.log(e);
}
javascript
javascript
New contributor
New contributor
New contributor
asked 2 days ago
Vijay
1164
1164
New contributor
New contributor
1
Why does this question have close votes? The problem is explained, there's an example and the code is there and seems to be working.
– IEatBagels
16 hours ago
add a comment |
1
Why does this question have close votes? The problem is explained, there's an example and the code is there and seems to be working.
– IEatBagels
16 hours ago
1
1
Why does this question have close votes? The problem is explained, there's an example and the code is there and seems to be working.
– IEatBagels
16 hours ago
Why does this question have close votes? The problem is explained, there's an example and the code is there and seems to be working.
– IEatBagels
16 hours ago
add a comment |
2 Answers
2
active
oldest
votes
up vote
1
down vote
accepted
Good algorithm
Your solution is good, however its implementation is somewhat poor.
Clear requirements
It is very unclear what inputs to expect so I must add...
The input arrays are sorted and contain unique values, I must assume a requirement that is true.
I deduce this from your code as if the above was not true your code would fail.
Style & code
- The variable names are too long. Remember code is always in context and if you are handling arrays do you really need to add that in their names?
- Don't copy the array, just push it to the result.
finalArray.push([...currentArray]);
can befinalArray.push(currentArray);
The copy halves the performance of your code (see below) - Use
undefined
rather thannull
- Simplify the code by using
else if
when possible. You have} else { if (currentArray) {
which can be} else if (currentArray) {
finalArray
should be a constant.- Don't add code that is not needed. The last statement block up assign
null
tocurrentArray
yet the variable is never used after that line.
Apart from the above points your algorithm is good as it has low complexity (if you use finalArray.push(currentArray)
you halve the complexity as [...currentArray] requires iteration of each item).
You missed the opportunity to exit early. If you pass the end of the either arrays you know that no more items need to be added, however you continue to the end of the first array, which if longer than the second could mean many rundundent iterations.
If you change the for loop to...
for (let i = 0; i < mainArray.length && compArrayIndex < compArray.length; i++) {
...you gain a reduction in overall complexity.
Cleaning up your solution
Thus we can rewrite your algorithm as
function extractRuns(main, comp) {
var seq, j = 0;
const result = ;
for (let i = 0; i < main.length && j < comp.length; i++) {
const e = main[i];
if (e === comp[j]) {
if (!seq) { seq = }
seq.push(e);
j++;
} else if (seq) {
result.push(seq);
seq = undefined;
}
}
if (seq) { result.push(seq) }
return result;
}
Short is not always best
I must point out that the existing answer by guest271314 is very poor as it has very bad complexity by using Array.includes
and is forced to iterate each item in the main array as it has no way to exit early from Array.reduce
.
Rewrite
I personally would have written the solution as below as it gains a little performance (not by reduced complexity) via an inner while loop. (I am a bit of an off grid performance freak :) )
function extractRuns(main, comp) { // both arrays must be sorted and contain unique values
var m = 0, c = 0, seq; // c and m are indexes
const result = , mLen = main.length, cLen = comp.length;
while (m < mLen && c < cLen) {
const a = main[m], b = comp[c];
if (a === b) {
c ++;
m ++;
result.push(seq = [a]);
while (m < mLen && r < cLen && main[m] === comp[c]) {
seq.push(main[m ++]);
c ++;
}
} else if (b < a) { c ++ }
else { m ++ }
}
return result;
}
But I think your solution is far more readable and only a few % points slower to not be an issue.
1
I agree with the review, although the long variable names were just for making my current solutions intentions more clear in the question. Thank you for the review.
– Vijay
yesterday
1
@Vijay Re long names, Understandable but we must take the code at face value. It is assumed that the posted code is working production (release) code. On that I did forget to make a point that it should also have been as afunction
but again I understand that you wrote it as an example.
– Blindman67
yesterday
1
@Blindman67 "I must point out that the existing answer by guest271314 is very poor" Your answer should stand on its own without any reference to another users' answer. You should be able to remove that portion of text from your answer without affecting the remainder of your answer. At a minimum instead of referring to this user in you answer you could have simply suggested to use.find()
instead of.includes()
as that appears to be the only criticism of the answer that you are citing. Did not ask you to review this users' answer though since you insisted on doing so do so constructively
– guest271314
yesterday
This is a good answer but I realllyyy can't agree with "The variable names are too long"
– IEatBagels
16 hours ago
@IEatBagels How doesmainArray
improve onmain
its an array why add it to the name.compArrayIndex
adds nothing to the readability of a 17 line function overj
as a standard iteration index name. Long names make long lines that often means breaking lines apart that could be single line statements and expressions. Good names are short, don't include type, and are always read in context of the code they are declared in from which comes most of the semantic meaning. Long names are for long functions with many variables declared off page, and globals, both of which are bad.
– Blindman67
15 hours ago
add a comment |
up vote
2
down vote
The code could be reduced to a single line by utilizing Array.prototype.reduce()
const mainArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
const compArray = [1, 2, 3, 6, 7, 11, 12, 13, 15];
const finalArray = mainArray.reduce((a, b) => {
// `c` is boolean result of checking if `compArray` includes `b`
// `x` is first, and if matching elements found, last array in `finalResult`
const [c, x] = [compArray.includes(b), a[a.length - 1]];
// if `c` push `b` to last array of `a`
if (c) x.push(b)
// else if `x.length` push a new array to `a`
else if (x.length) a.push();
// return `a`
return a;
}, []); // pass initial array containing single array `a` to `reduce`
console.log(finalArray);
To filter empty arrays in the case of[1, 2, 3, 6, 7, 11, 12, 13]
you can chain.filter(n=>n.length)
– guest271314
2 days ago
I must point out your answer is not really a review, that the solution you give is O(n^2) while the op's is O(n), and that the comments are too much.. I would have down voted if you were not a newbie but rather I upvote and encourage you to keep posting, keeping these points in mind of course. Really!!!.// return 'a'
forreturn a;
and// else if
x.length` push a new array toa`` for
else if (x.length) a.push();`
– Blindman67
yesterday
@Blindman67 Not sure what you mean? How did you determine O(n^2) and O(n)? Is your only criticism the use of.includes()
instead of.find()
? "down" vote is meaningless to this user.
– guest271314
yesterday
Array.includes
orArray.find
are both iterative searches, when done inside another iteration the worst case is O(n^2) with n the mean array size. Plus there is no way to exit early fromArray.reduce
if the other array is shorter.
– Blindman67
yesterday
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
accepted
Good algorithm
Your solution is good, however its implementation is somewhat poor.
Clear requirements
It is very unclear what inputs to expect so I must add...
The input arrays are sorted and contain unique values, I must assume a requirement that is true.
I deduce this from your code as if the above was not true your code would fail.
Style & code
- The variable names are too long. Remember code is always in context and if you are handling arrays do you really need to add that in their names?
- Don't copy the array, just push it to the result.
finalArray.push([...currentArray]);
can befinalArray.push(currentArray);
The copy halves the performance of your code (see below) - Use
undefined
rather thannull
- Simplify the code by using
else if
when possible. You have} else { if (currentArray) {
which can be} else if (currentArray) {
finalArray
should be a constant.- Don't add code that is not needed. The last statement block up assign
null
tocurrentArray
yet the variable is never used after that line.
Apart from the above points your algorithm is good as it has low complexity (if you use finalArray.push(currentArray)
you halve the complexity as [...currentArray] requires iteration of each item).
You missed the opportunity to exit early. If you pass the end of the either arrays you know that no more items need to be added, however you continue to the end of the first array, which if longer than the second could mean many rundundent iterations.
If you change the for loop to...
for (let i = 0; i < mainArray.length && compArrayIndex < compArray.length; i++) {
...you gain a reduction in overall complexity.
Cleaning up your solution
Thus we can rewrite your algorithm as
function extractRuns(main, comp) {
var seq, j = 0;
const result = ;
for (let i = 0; i < main.length && j < comp.length; i++) {
const e = main[i];
if (e === comp[j]) {
if (!seq) { seq = }
seq.push(e);
j++;
} else if (seq) {
result.push(seq);
seq = undefined;
}
}
if (seq) { result.push(seq) }
return result;
}
Short is not always best
I must point out that the existing answer by guest271314 is very poor as it has very bad complexity by using Array.includes
and is forced to iterate each item in the main array as it has no way to exit early from Array.reduce
.
Rewrite
I personally would have written the solution as below as it gains a little performance (not by reduced complexity) via an inner while loop. (I am a bit of an off grid performance freak :) )
function extractRuns(main, comp) { // both arrays must be sorted and contain unique values
var m = 0, c = 0, seq; // c and m are indexes
const result = , mLen = main.length, cLen = comp.length;
while (m < mLen && c < cLen) {
const a = main[m], b = comp[c];
if (a === b) {
c ++;
m ++;
result.push(seq = [a]);
while (m < mLen && r < cLen && main[m] === comp[c]) {
seq.push(main[m ++]);
c ++;
}
} else if (b < a) { c ++ }
else { m ++ }
}
return result;
}
But I think your solution is far more readable and only a few % points slower to not be an issue.
1
I agree with the review, although the long variable names were just for making my current solutions intentions more clear in the question. Thank you for the review.
– Vijay
yesterday
1
@Vijay Re long names, Understandable but we must take the code at face value. It is assumed that the posted code is working production (release) code. On that I did forget to make a point that it should also have been as afunction
but again I understand that you wrote it as an example.
– Blindman67
yesterday
1
@Blindman67 "I must point out that the existing answer by guest271314 is very poor" Your answer should stand on its own without any reference to another users' answer. You should be able to remove that portion of text from your answer without affecting the remainder of your answer. At a minimum instead of referring to this user in you answer you could have simply suggested to use.find()
instead of.includes()
as that appears to be the only criticism of the answer that you are citing. Did not ask you to review this users' answer though since you insisted on doing so do so constructively
– guest271314
yesterday
This is a good answer but I realllyyy can't agree with "The variable names are too long"
– IEatBagels
16 hours ago
@IEatBagels How doesmainArray
improve onmain
its an array why add it to the name.compArrayIndex
adds nothing to the readability of a 17 line function overj
as a standard iteration index name. Long names make long lines that often means breaking lines apart that could be single line statements and expressions. Good names are short, don't include type, and are always read in context of the code they are declared in from which comes most of the semantic meaning. Long names are for long functions with many variables declared off page, and globals, both of which are bad.
– Blindman67
15 hours ago
add a comment |
up vote
1
down vote
accepted
Good algorithm
Your solution is good, however its implementation is somewhat poor.
Clear requirements
It is very unclear what inputs to expect so I must add...
The input arrays are sorted and contain unique values, I must assume a requirement that is true.
I deduce this from your code as if the above was not true your code would fail.
Style & code
- The variable names are too long. Remember code is always in context and if you are handling arrays do you really need to add that in their names?
- Don't copy the array, just push it to the result.
finalArray.push([...currentArray]);
can befinalArray.push(currentArray);
The copy halves the performance of your code (see below) - Use
undefined
rather thannull
- Simplify the code by using
else if
when possible. You have} else { if (currentArray) {
which can be} else if (currentArray) {
finalArray
should be a constant.- Don't add code that is not needed. The last statement block up assign
null
tocurrentArray
yet the variable is never used after that line.
Apart from the above points your algorithm is good as it has low complexity (if you use finalArray.push(currentArray)
you halve the complexity as [...currentArray] requires iteration of each item).
You missed the opportunity to exit early. If you pass the end of the either arrays you know that no more items need to be added, however you continue to the end of the first array, which if longer than the second could mean many rundundent iterations.
If you change the for loop to...
for (let i = 0; i < mainArray.length && compArrayIndex < compArray.length; i++) {
...you gain a reduction in overall complexity.
Cleaning up your solution
Thus we can rewrite your algorithm as
function extractRuns(main, comp) {
var seq, j = 0;
const result = ;
for (let i = 0; i < main.length && j < comp.length; i++) {
const e = main[i];
if (e === comp[j]) {
if (!seq) { seq = }
seq.push(e);
j++;
} else if (seq) {
result.push(seq);
seq = undefined;
}
}
if (seq) { result.push(seq) }
return result;
}
Short is not always best
I must point out that the existing answer by guest271314 is very poor as it has very bad complexity by using Array.includes
and is forced to iterate each item in the main array as it has no way to exit early from Array.reduce
.
Rewrite
I personally would have written the solution as below as it gains a little performance (not by reduced complexity) via an inner while loop. (I am a bit of an off grid performance freak :) )
function extractRuns(main, comp) { // both arrays must be sorted and contain unique values
var m = 0, c = 0, seq; // c and m are indexes
const result = , mLen = main.length, cLen = comp.length;
while (m < mLen && c < cLen) {
const a = main[m], b = comp[c];
if (a === b) {
c ++;
m ++;
result.push(seq = [a]);
while (m < mLen && r < cLen && main[m] === comp[c]) {
seq.push(main[m ++]);
c ++;
}
} else if (b < a) { c ++ }
else { m ++ }
}
return result;
}
But I think your solution is far more readable and only a few % points slower to not be an issue.
1
I agree with the review, although the long variable names were just for making my current solutions intentions more clear in the question. Thank you for the review.
– Vijay
yesterday
1
@Vijay Re long names, Understandable but we must take the code at face value. It is assumed that the posted code is working production (release) code. On that I did forget to make a point that it should also have been as afunction
but again I understand that you wrote it as an example.
– Blindman67
yesterday
1
@Blindman67 "I must point out that the existing answer by guest271314 is very poor" Your answer should stand on its own without any reference to another users' answer. You should be able to remove that portion of text from your answer without affecting the remainder of your answer. At a minimum instead of referring to this user in you answer you could have simply suggested to use.find()
instead of.includes()
as that appears to be the only criticism of the answer that you are citing. Did not ask you to review this users' answer though since you insisted on doing so do so constructively
– guest271314
yesterday
This is a good answer but I realllyyy can't agree with "The variable names are too long"
– IEatBagels
16 hours ago
@IEatBagels How doesmainArray
improve onmain
its an array why add it to the name.compArrayIndex
adds nothing to the readability of a 17 line function overj
as a standard iteration index name. Long names make long lines that often means breaking lines apart that could be single line statements and expressions. Good names are short, don't include type, and are always read in context of the code they are declared in from which comes most of the semantic meaning. Long names are for long functions with many variables declared off page, and globals, both of which are bad.
– Blindman67
15 hours ago
add a comment |
up vote
1
down vote
accepted
up vote
1
down vote
accepted
Good algorithm
Your solution is good, however its implementation is somewhat poor.
Clear requirements
It is very unclear what inputs to expect so I must add...
The input arrays are sorted and contain unique values, I must assume a requirement that is true.
I deduce this from your code as if the above was not true your code would fail.
Style & code
- The variable names are too long. Remember code is always in context and if you are handling arrays do you really need to add that in their names?
- Don't copy the array, just push it to the result.
finalArray.push([...currentArray]);
can befinalArray.push(currentArray);
The copy halves the performance of your code (see below) - Use
undefined
rather thannull
- Simplify the code by using
else if
when possible. You have} else { if (currentArray) {
which can be} else if (currentArray) {
finalArray
should be a constant.- Don't add code that is not needed. The last statement block up assign
null
tocurrentArray
yet the variable is never used after that line.
Apart from the above points your algorithm is good as it has low complexity (if you use finalArray.push(currentArray)
you halve the complexity as [...currentArray] requires iteration of each item).
You missed the opportunity to exit early. If you pass the end of the either arrays you know that no more items need to be added, however you continue to the end of the first array, which if longer than the second could mean many rundundent iterations.
If you change the for loop to...
for (let i = 0; i < mainArray.length && compArrayIndex < compArray.length; i++) {
...you gain a reduction in overall complexity.
Cleaning up your solution
Thus we can rewrite your algorithm as
function extractRuns(main, comp) {
var seq, j = 0;
const result = ;
for (let i = 0; i < main.length && j < comp.length; i++) {
const e = main[i];
if (e === comp[j]) {
if (!seq) { seq = }
seq.push(e);
j++;
} else if (seq) {
result.push(seq);
seq = undefined;
}
}
if (seq) { result.push(seq) }
return result;
}
Short is not always best
I must point out that the existing answer by guest271314 is very poor as it has very bad complexity by using Array.includes
and is forced to iterate each item in the main array as it has no way to exit early from Array.reduce
.
Rewrite
I personally would have written the solution as below as it gains a little performance (not by reduced complexity) via an inner while loop. (I am a bit of an off grid performance freak :) )
function extractRuns(main, comp) { // both arrays must be sorted and contain unique values
var m = 0, c = 0, seq; // c and m are indexes
const result = , mLen = main.length, cLen = comp.length;
while (m < mLen && c < cLen) {
const a = main[m], b = comp[c];
if (a === b) {
c ++;
m ++;
result.push(seq = [a]);
while (m < mLen && r < cLen && main[m] === comp[c]) {
seq.push(main[m ++]);
c ++;
}
} else if (b < a) { c ++ }
else { m ++ }
}
return result;
}
But I think your solution is far more readable and only a few % points slower to not be an issue.
Good algorithm
Your solution is good, however its implementation is somewhat poor.
Clear requirements
It is very unclear what inputs to expect so I must add...
The input arrays are sorted and contain unique values, I must assume a requirement that is true.
I deduce this from your code as if the above was not true your code would fail.
Style & code
- The variable names are too long. Remember code is always in context and if you are handling arrays do you really need to add that in their names?
- Don't copy the array, just push it to the result.
finalArray.push([...currentArray]);
can befinalArray.push(currentArray);
The copy halves the performance of your code (see below) - Use
undefined
rather thannull
- Simplify the code by using
else if
when possible. You have} else { if (currentArray) {
which can be} else if (currentArray) {
finalArray
should be a constant.- Don't add code that is not needed. The last statement block up assign
null
tocurrentArray
yet the variable is never used after that line.
Apart from the above points your algorithm is good as it has low complexity (if you use finalArray.push(currentArray)
you halve the complexity as [...currentArray] requires iteration of each item).
You missed the opportunity to exit early. If you pass the end of the either arrays you know that no more items need to be added, however you continue to the end of the first array, which if longer than the second could mean many rundundent iterations.
If you change the for loop to...
for (let i = 0; i < mainArray.length && compArrayIndex < compArray.length; i++) {
...you gain a reduction in overall complexity.
Cleaning up your solution
Thus we can rewrite your algorithm as
function extractRuns(main, comp) {
var seq, j = 0;
const result = ;
for (let i = 0; i < main.length && j < comp.length; i++) {
const e = main[i];
if (e === comp[j]) {
if (!seq) { seq = }
seq.push(e);
j++;
} else if (seq) {
result.push(seq);
seq = undefined;
}
}
if (seq) { result.push(seq) }
return result;
}
Short is not always best
I must point out that the existing answer by guest271314 is very poor as it has very bad complexity by using Array.includes
and is forced to iterate each item in the main array as it has no way to exit early from Array.reduce
.
Rewrite
I personally would have written the solution as below as it gains a little performance (not by reduced complexity) via an inner while loop. (I am a bit of an off grid performance freak :) )
function extractRuns(main, comp) { // both arrays must be sorted and contain unique values
var m = 0, c = 0, seq; // c and m are indexes
const result = , mLen = main.length, cLen = comp.length;
while (m < mLen && c < cLen) {
const a = main[m], b = comp[c];
if (a === b) {
c ++;
m ++;
result.push(seq = [a]);
while (m < mLen && r < cLen && main[m] === comp[c]) {
seq.push(main[m ++]);
c ++;
}
} else if (b < a) { c ++ }
else { m ++ }
}
return result;
}
But I think your solution is far more readable and only a few % points slower to not be an issue.
edited yesterday
answered yesterday
Blindman67
6,6241521
6,6241521
1
I agree with the review, although the long variable names were just for making my current solutions intentions more clear in the question. Thank you for the review.
– Vijay
yesterday
1
@Vijay Re long names, Understandable but we must take the code at face value. It is assumed that the posted code is working production (release) code. On that I did forget to make a point that it should also have been as afunction
but again I understand that you wrote it as an example.
– Blindman67
yesterday
1
@Blindman67 "I must point out that the existing answer by guest271314 is very poor" Your answer should stand on its own without any reference to another users' answer. You should be able to remove that portion of text from your answer without affecting the remainder of your answer. At a minimum instead of referring to this user in you answer you could have simply suggested to use.find()
instead of.includes()
as that appears to be the only criticism of the answer that you are citing. Did not ask you to review this users' answer though since you insisted on doing so do so constructively
– guest271314
yesterday
This is a good answer but I realllyyy can't agree with "The variable names are too long"
– IEatBagels
16 hours ago
@IEatBagels How doesmainArray
improve onmain
its an array why add it to the name.compArrayIndex
adds nothing to the readability of a 17 line function overj
as a standard iteration index name. Long names make long lines that often means breaking lines apart that could be single line statements and expressions. Good names are short, don't include type, and are always read in context of the code they are declared in from which comes most of the semantic meaning. Long names are for long functions with many variables declared off page, and globals, both of which are bad.
– Blindman67
15 hours ago
add a comment |
1
I agree with the review, although the long variable names were just for making my current solutions intentions more clear in the question. Thank you for the review.
– Vijay
yesterday
1
@Vijay Re long names, Understandable but we must take the code at face value. It is assumed that the posted code is working production (release) code. On that I did forget to make a point that it should also have been as afunction
but again I understand that you wrote it as an example.
– Blindman67
yesterday
1
@Blindman67 "I must point out that the existing answer by guest271314 is very poor" Your answer should stand on its own without any reference to another users' answer. You should be able to remove that portion of text from your answer without affecting the remainder of your answer. At a minimum instead of referring to this user in you answer you could have simply suggested to use.find()
instead of.includes()
as that appears to be the only criticism of the answer that you are citing. Did not ask you to review this users' answer though since you insisted on doing so do so constructively
– guest271314
yesterday
This is a good answer but I realllyyy can't agree with "The variable names are too long"
– IEatBagels
16 hours ago
@IEatBagels How doesmainArray
improve onmain
its an array why add it to the name.compArrayIndex
adds nothing to the readability of a 17 line function overj
as a standard iteration index name. Long names make long lines that often means breaking lines apart that could be single line statements and expressions. Good names are short, don't include type, and are always read in context of the code they are declared in from which comes most of the semantic meaning. Long names are for long functions with many variables declared off page, and globals, both of which are bad.
– Blindman67
15 hours ago
1
1
I agree with the review, although the long variable names were just for making my current solutions intentions more clear in the question. Thank you for the review.
– Vijay
yesterday
I agree with the review, although the long variable names were just for making my current solutions intentions more clear in the question. Thank you for the review.
– Vijay
yesterday
1
1
@Vijay Re long names, Understandable but we must take the code at face value. It is assumed that the posted code is working production (release) code. On that I did forget to make a point that it should also have been as a
function
but again I understand that you wrote it as an example.– Blindman67
yesterday
@Vijay Re long names, Understandable but we must take the code at face value. It is assumed that the posted code is working production (release) code. On that I did forget to make a point that it should also have been as a
function
but again I understand that you wrote it as an example.– Blindman67
yesterday
1
1
@Blindman67 "I must point out that the existing answer by guest271314 is very poor" Your answer should stand on its own without any reference to another users' answer. You should be able to remove that portion of text from your answer without affecting the remainder of your answer. At a minimum instead of referring to this user in you answer you could have simply suggested to use
.find()
instead of .includes()
as that appears to be the only criticism of the answer that you are citing. Did not ask you to review this users' answer though since you insisted on doing so do so constructively– guest271314
yesterday
@Blindman67 "I must point out that the existing answer by guest271314 is very poor" Your answer should stand on its own without any reference to another users' answer. You should be able to remove that portion of text from your answer without affecting the remainder of your answer. At a minimum instead of referring to this user in you answer you could have simply suggested to use
.find()
instead of .includes()
as that appears to be the only criticism of the answer that you are citing. Did not ask you to review this users' answer though since you insisted on doing so do so constructively– guest271314
yesterday
This is a good answer but I realllyyy can't agree with "The variable names are too long"
– IEatBagels
16 hours ago
This is a good answer but I realllyyy can't agree with "The variable names are too long"
– IEatBagels
16 hours ago
@IEatBagels How does
mainArray
improve on main
its an array why add it to the name. compArrayIndex
adds nothing to the readability of a 17 line function over j
as a standard iteration index name. Long names make long lines that often means breaking lines apart that could be single line statements and expressions. Good names are short, don't include type, and are always read in context of the code they are declared in from which comes most of the semantic meaning. Long names are for long functions with many variables declared off page, and globals, both of which are bad.– Blindman67
15 hours ago
@IEatBagels How does
mainArray
improve on main
its an array why add it to the name. compArrayIndex
adds nothing to the readability of a 17 line function over j
as a standard iteration index name. Long names make long lines that often means breaking lines apart that could be single line statements and expressions. Good names are short, don't include type, and are always read in context of the code they are declared in from which comes most of the semantic meaning. Long names are for long functions with many variables declared off page, and globals, both of which are bad.– Blindman67
15 hours ago
add a comment |
up vote
2
down vote
The code could be reduced to a single line by utilizing Array.prototype.reduce()
const mainArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
const compArray = [1, 2, 3, 6, 7, 11, 12, 13, 15];
const finalArray = mainArray.reduce((a, b) => {
// `c` is boolean result of checking if `compArray` includes `b`
// `x` is first, and if matching elements found, last array in `finalResult`
const [c, x] = [compArray.includes(b), a[a.length - 1]];
// if `c` push `b` to last array of `a`
if (c) x.push(b)
// else if `x.length` push a new array to `a`
else if (x.length) a.push();
// return `a`
return a;
}, []); // pass initial array containing single array `a` to `reduce`
console.log(finalArray);
To filter empty arrays in the case of[1, 2, 3, 6, 7, 11, 12, 13]
you can chain.filter(n=>n.length)
– guest271314
2 days ago
I must point out your answer is not really a review, that the solution you give is O(n^2) while the op's is O(n), and that the comments are too much.. I would have down voted if you were not a newbie but rather I upvote and encourage you to keep posting, keeping these points in mind of course. Really!!!.// return 'a'
forreturn a;
and// else if
x.length` push a new array toa`` for
else if (x.length) a.push();`
– Blindman67
yesterday
@Blindman67 Not sure what you mean? How did you determine O(n^2) and O(n)? Is your only criticism the use of.includes()
instead of.find()
? "down" vote is meaningless to this user.
– guest271314
yesterday
Array.includes
orArray.find
are both iterative searches, when done inside another iteration the worst case is O(n^2) with n the mean array size. Plus there is no way to exit early fromArray.reduce
if the other array is shorter.
– Blindman67
yesterday
add a comment |
up vote
2
down vote
The code could be reduced to a single line by utilizing Array.prototype.reduce()
const mainArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
const compArray = [1, 2, 3, 6, 7, 11, 12, 13, 15];
const finalArray = mainArray.reduce((a, b) => {
// `c` is boolean result of checking if `compArray` includes `b`
// `x` is first, and if matching elements found, last array in `finalResult`
const [c, x] = [compArray.includes(b), a[a.length - 1]];
// if `c` push `b` to last array of `a`
if (c) x.push(b)
// else if `x.length` push a new array to `a`
else if (x.length) a.push();
// return `a`
return a;
}, []); // pass initial array containing single array `a` to `reduce`
console.log(finalArray);
To filter empty arrays in the case of[1, 2, 3, 6, 7, 11, 12, 13]
you can chain.filter(n=>n.length)
– guest271314
2 days ago
I must point out your answer is not really a review, that the solution you give is O(n^2) while the op's is O(n), and that the comments are too much.. I would have down voted if you were not a newbie but rather I upvote and encourage you to keep posting, keeping these points in mind of course. Really!!!.// return 'a'
forreturn a;
and// else if
x.length` push a new array toa`` for
else if (x.length) a.push();`
– Blindman67
yesterday
@Blindman67 Not sure what you mean? How did you determine O(n^2) and O(n)? Is your only criticism the use of.includes()
instead of.find()
? "down" vote is meaningless to this user.
– guest271314
yesterday
Array.includes
orArray.find
are both iterative searches, when done inside another iteration the worst case is O(n^2) with n the mean array size. Plus there is no way to exit early fromArray.reduce
if the other array is shorter.
– Blindman67
yesterday
add a comment |
up vote
2
down vote
up vote
2
down vote
The code could be reduced to a single line by utilizing Array.prototype.reduce()
const mainArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
const compArray = [1, 2, 3, 6, 7, 11, 12, 13, 15];
const finalArray = mainArray.reduce((a, b) => {
// `c` is boolean result of checking if `compArray` includes `b`
// `x` is first, and if matching elements found, last array in `finalResult`
const [c, x] = [compArray.includes(b), a[a.length - 1]];
// if `c` push `b` to last array of `a`
if (c) x.push(b)
// else if `x.length` push a new array to `a`
else if (x.length) a.push();
// return `a`
return a;
}, []); // pass initial array containing single array `a` to `reduce`
console.log(finalArray);
The code could be reduced to a single line by utilizing Array.prototype.reduce()
const mainArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
const compArray = [1, 2, 3, 6, 7, 11, 12, 13, 15];
const finalArray = mainArray.reduce((a, b) => {
// `c` is boolean result of checking if `compArray` includes `b`
// `x` is first, and if matching elements found, last array in `finalResult`
const [c, x] = [compArray.includes(b), a[a.length - 1]];
// if `c` push `b` to last array of `a`
if (c) x.push(b)
// else if `x.length` push a new array to `a`
else if (x.length) a.push();
// return `a`
return a;
}, []); // pass initial array containing single array `a` to `reduce`
console.log(finalArray);
const mainArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
const compArray = [1, 2, 3, 6, 7, 11, 12, 13, 15];
const finalArray = mainArray.reduce((a, b) => {
// `c` is boolean result of checking if `compArray` includes `b`
// `x` is first, and if matching elements found, last array in `finalResult`
const [c, x] = [compArray.includes(b), a[a.length - 1]];
// if `c` push `b` to last array of `a`
if (c) x.push(b)
// else if `x.length` push a new array to `a`
else if (x.length) a.push();
// return `a`
return a;
}, []); // pass initial array containing single array `a` to `reduce`
console.log(finalArray);
const mainArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
const compArray = [1, 2, 3, 6, 7, 11, 12, 13, 15];
const finalArray = mainArray.reduce((a, b) => {
// `c` is boolean result of checking if `compArray` includes `b`
// `x` is first, and if matching elements found, last array in `finalResult`
const [c, x] = [compArray.includes(b), a[a.length - 1]];
// if `c` push `b` to last array of `a`
if (c) x.push(b)
// else if `x.length` push a new array to `a`
else if (x.length) a.push();
// return `a`
return a;
}, []); // pass initial array containing single array `a` to `reduce`
console.log(finalArray);
answered 2 days ago
guest271314
1615
1615
To filter empty arrays in the case of[1, 2, 3, 6, 7, 11, 12, 13]
you can chain.filter(n=>n.length)
– guest271314
2 days ago
I must point out your answer is not really a review, that the solution you give is O(n^2) while the op's is O(n), and that the comments are too much.. I would have down voted if you were not a newbie but rather I upvote and encourage you to keep posting, keeping these points in mind of course. Really!!!.// return 'a'
forreturn a;
and// else if
x.length` push a new array toa`` for
else if (x.length) a.push();`
– Blindman67
yesterday
@Blindman67 Not sure what you mean? How did you determine O(n^2) and O(n)? Is your only criticism the use of.includes()
instead of.find()
? "down" vote is meaningless to this user.
– guest271314
yesterday
Array.includes
orArray.find
are both iterative searches, when done inside another iteration the worst case is O(n^2) with n the mean array size. Plus there is no way to exit early fromArray.reduce
if the other array is shorter.
– Blindman67
yesterday
add a comment |
To filter empty arrays in the case of[1, 2, 3, 6, 7, 11, 12, 13]
you can chain.filter(n=>n.length)
– guest271314
2 days ago
I must point out your answer is not really a review, that the solution you give is O(n^2) while the op's is O(n), and that the comments are too much.. I would have down voted if you were not a newbie but rather I upvote and encourage you to keep posting, keeping these points in mind of course. Really!!!.// return 'a'
forreturn a;
and// else if
x.length` push a new array toa`` for
else if (x.length) a.push();`
– Blindman67
yesterday
@Blindman67 Not sure what you mean? How did you determine O(n^2) and O(n)? Is your only criticism the use of.includes()
instead of.find()
? "down" vote is meaningless to this user.
– guest271314
yesterday
Array.includes
orArray.find
are both iterative searches, when done inside another iteration the worst case is O(n^2) with n the mean array size. Plus there is no way to exit early fromArray.reduce
if the other array is shorter.
– Blindman67
yesterday
To filter empty arrays in the case of
[1, 2, 3, 6, 7, 11, 12, 13]
you can chain .filter(n=>n.length)
– guest271314
2 days ago
To filter empty arrays in the case of
[1, 2, 3, 6, 7, 11, 12, 13]
you can chain .filter(n=>n.length)
– guest271314
2 days ago
I must point out your answer is not really a review, that the solution you give is O(n^2) while the op's is O(n), and that the comments are too much.. I would have down voted if you were not a newbie but rather I upvote and encourage you to keep posting, keeping these points in mind of course. Really!!!
.// return 'a'
for return a;
and // else if
x.length` push a new array to a`` for
else if (x.length) a.push();`– Blindman67
yesterday
I must point out your answer is not really a review, that the solution you give is O(n^2) while the op's is O(n), and that the comments are too much.. I would have down voted if you were not a newbie but rather I upvote and encourage you to keep posting, keeping these points in mind of course. Really!!!
.// return 'a'
for return a;
and // else if
x.length` push a new array to a`` for
else if (x.length) a.push();`– Blindman67
yesterday
@Blindman67 Not sure what you mean? How did you determine O(n^2) and O(n)? Is your only criticism the use of
.includes()
instead of .find()
? "down" vote is meaningless to this user.– guest271314
yesterday
@Blindman67 Not sure what you mean? How did you determine O(n^2) and O(n)? Is your only criticism the use of
.includes()
instead of .find()
? "down" vote is meaningless to this user.– guest271314
yesterday
Array.includes
or Array.find
are both iterative searches, when done inside another iteration the worst case is O(n^2) with n the mean array size. Plus there is no way to exit early from Array.reduce
if the other array is shorter.– Blindman67
yesterday
Array.includes
or Array.find
are both iterative searches, when done inside another iteration the worst case is O(n^2) with n the mean array size. Plus there is no way to exit early from Array.reduce
if the other array is shorter.– Blindman67
yesterday
add a comment |
Vijay is a new contributor. Be nice, and check out our Code of Conduct.
Vijay is a new contributor. Be nice, and check out our Code of Conduct.
Vijay is a new contributor. Be nice, and check out our Code of Conduct.
Vijay is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f208561%2fconstruct-an-2d-array-of-contiguous-elements-comparing-master-and-incident-array%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
Why does this question have close votes? The problem is explained, there's an example and the code is there and seems to be working.
– IEatBagels
16 hours ago