1

I have an array like below

const num = [1,2,3,4,5,6,7];

and boundary condition values,

var first = 6
var second = 3

Expected Output now based on this is like below,

[6,7,1,2,3]

Explain:

The result should combine 2 arrays:

  1. >= first in the left [6, 7]
  2. <= second in the right [1,2,3]

I tried trying something like below but array positions are not as I mentioned above.

const result = num.filter((n,p) => {
  if(p >= num.indexOf(first)) {return n}
  else if(p <= num.indexOf(second)) {return n}
});


console.log(result) // [1,2,3,6,7]

an alternative way is below but that is not efficient as I need to loop twice.

const num = [1,2,3,4,5,6,7];
var first = 6
var second = 3
var arr = []
num.forEach((n,p) => {
  if(p >= num.indexOf(first)) {arr.push(n)}
});
num.forEach((n,p) => {
  if(p <= num.indexOf(second)) {arr.push(n)}
});

console.log(arr) //[6,7,1,2,3]

Any better way to achieve this?

7
  • What is the expected output if the first and second boundary conditions are swapped around? Commented Apr 7, 2021 at 6:05
  • @Terry Don't worry Terry I already handled that situation. But, here am looking for a better way without doing the filter twice. Commented Apr 7, 2021 at 6:12
  • 1
    I ran your second snippet with first and second swapped and got the output [3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6]. You need to properly say the condition based upon which you want the array. Commented Apr 7, 2021 at 6:18
  • I've just mentioned the condition in my answer below. You can take a look at it @Xua & Terry Commented Apr 7, 2021 at 6:34
  • 1
    That's cool! .... Commented Apr 7, 2021 at 6:40

5 Answers 5

2
var num = [1, 2, 3, 4, 5, 6, 7];
var first = 6;
var second = 3;
const res = [
  ...num.filter((n) => n >= first),
  ...num.filter((n) => n <= second)
];
console.log(res); // [6,7,1,2,3]

Update:

loop once:

var num = [1, 2, 3, 4, 5, 6, 7];
var first = 6;
var second = 3;
var left = [];
var right = [];
num.forEach((n) => {
  if (n >= first) left.push(n);
  if (n <= second) right.push(n);
});
const res = [...left, ...right];
console.log(res); // [6,7,1,2,3]
Sign up to request clarification or add additional context in comments.

2 Comments

similar thing I mentioned this in my question itself, This is not the efficient way as it take two filters.
Updated: Space for time,just loop once
2

Your request seems special, to say the least, but the following should do the job:

const arr=[1,2,3,4,5,6,7];

// looking at positions of elements:
const getSubArraysPos=(ar,m,n)=>[...ar,...ar].slice(m-1,ar.length+n);
console.log(getSubArraysPos(arr,6,3))

// looking at array values:
const getSubArraysVal=(ar,m,n)=>[].concat.call(...ar.reduce((a,c)=>{
  if (m>n) { if(c>=m) a[0].push(c); else if (c<=n) a[1].push(c); }
  else if(c>=m && c<=n) a[0].push(c);
  return a }, [[],[]]));
  
console.log("6,3:",getSubArraysPos(arr,6,3));
console.log("5,2:",getSubArraysVal(arr,5,2));
console.log("2,5:",getSubArraysVal(arr,2,5))

The code is probably a bit "terse", but I was just trying to make it as "one-line" as possible.

6 Comments

Thank you sir, but I need to check the time complexity for your version and the reduced function to mark this as the answer.
I also just realised that you probably want to look at the values of the array items and not at their position, as I did here.
What happens if the array is not sorted?
I will get two values from server, sometimes it will we 2,5 and sometimes it is 5,2 in both cases I need to fetch array like 2,5 -> [2,3,4,5] 5,2 -> [5,6,7,1,2]
Yes, As I guess above. @VikasAcharya
|
1

Firstly, I want to clarify the requirement, the result should combine 2 arrays:

  1. >= first in the left [6, 7]
  2. <= second in the right [1,2,3]

Output:1 & 2 = [6,7,1,2,3]


Solution:

The easy way is to use Array#reduce with initializing result as an object like this {first:[], second: []}. After that, use spread to concatenate 2 arrays.

As a result, you just need O(n) time complexity.

const num = [1,2,3,4,5,6,7];
var first = 6, second = 3;

const result = num.reduce((acc, curr) => {
  if(curr >= first) acc.first.push(curr);
  if(curr <= second) acc.second.push(curr);
  
  return acc;
}, {first:[], second: []});
console.log([...result.first, ...result.second]);

6 Comments

Sorry I didn't downvote, but you change boundary condition second to 7. can you tell me why
I've updated my answer with the detailed request explanation. You should mention it in your post @VikasAcharya
sorry what i should mention?
I've just edited your post with the Explain section. Pls kindly take a look at it.
After that, you should remove all irrelevant comments in my answer here, here. Thanks. @VikasAcharya
|
1

Your initial solution with .filter mostly works, but .filter can't reorder an array.

Find the index of the first value. Use it to slice off the end of the array. Find the second value. Use it to slice off the beginning of the array. Join the two pieces.

const secondIdx = num.indexOf(second);
const firstIdx = num.indexOf(first, second+1);
const results = num.slice(firstIdx).concat(num.slice(0, secondIdx+1));

1 Comment

This seems good, I need to check time complexity. Thank you
0

I'm posting my own answer as above answers have some or other problem

function arr(num, first, second){
 let arr = num.reduce((acc, v, i) => {
  let i1 = num.indexOf(first)
  let i2 = num.indexOf(second)
  if(i1 < i2 && i >= i1 && i <= i2) acc['a'].push(v)
  if(i1 > i2 && i <= i2){
    acc['t1'].push(v) 
  } 
  if(i1 > i2 && i >= i1) {
    acc['t2'].push(v) 
  }
  if(i1 > i2) acc['a'] = [...acc['t2'], ...acc['t1']]
  return acc
}, {a : [], t1: [], t2: []})

return arr['a']
}

let num = [1,2,3,4,5,6,7];
console.log(arr(num,2,5))
console.log(arr(num,5,2))
console.log(arr(num,3,6))
console.log(arr(num,6,3))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.