alias51
alias51

Reputation: 8608

How to map two arrays based on comparative value

I have two arrays:

A sequential array of numbers between 1-8, in increments of 1:

a = [1,2,3,4,5,6,7,8]

A sequential array of numbers between 1-8, with random increments:

b = [1,2,5,7]

I want to create a list of {a:val, b:val} dict pairs, where the value of b is only the next in the array if it is equal or greater to the value of a:

c = [
       {a:1, b:1}, 
       {a:2, b:2}, 
       {a:3, b:2}, 
       {a:4, b:2}, 
       {a:5, b:5}, 
       {a:6, b:5}, 
       {a:7, b:7}, 
       {a:8, b:7}
   ]

Is there an easy way to do this? I thought about using compounding $.each loops to build new arrays and increment values, but it seems as though this is overkill?

Upvotes: 1

Views: 380

Answers (2)

collapsar
collapsar

Reputation: 17238

The first array is actually redundant - the only significant information it carries is the number of elements.

The following code determines the difference between 2 adjacent threshold values from array b. This is 1 less the number of array elements with object property b set to the lower of these threshold values.

The target array is constructed as the array of object properties b in proper order. The resulting value list is mapped to the desired format.

The code may be optimized. It should run fast if the length of array b is much less than the length of array a. This hypothesis is not tested though and given the low complexity of the code/data structures will probably be insignificant.

let a = [1, 2, 3, 4, 5, 6, 7, 8]
  , b = [1, 2, 5, 7]
  , c = []
  , n_last = 1
  ;

b.forEach ( (pn_current, pn_idx) => {
    c.push( ...((new Array(pn_current - n_last)).fill(n_last)) );
    n_last = pn_current;
});
c.push( ...((new Array(a.length + 1 - n_last)).fill(n_last)) );

c = c.map ( ( pn_entry, pn_idx ) => { return { a: pn_idx+1, b: pn_entry }; } );

console.log(c);

Upvotes: 0

Code Maniac
Code Maniac

Reputation: 37755

You can use map and shift

  • Loop over first array.
  • If the value of current element is greater then first element on second array remove first element from second array, ( except when the length is less then 2)
  • return object in desired format

let a = [1, 2, 3, 4, 5, 6, 7, 8]
let b = [1, 2, 5, 7]

let final = a.map(v => {
  if (v >= b[1] && b.length > 1) {
    b.shift()
  }
  return {
    a: v,
    b: b[0]
  }
})

console.log(final)

This mutates second array if you don't want to mutate you can use a index variable and increment it based on condition

let a = [1, 2, 3, 4, 5, 6, 7, 8]
let b = [1, 2, 5, 7]
let index = 0
let final = a.map(v => {
  if (v >= b[index+1] && b.length - 1 > index ) {
    index++
  }
  return {
    a: v,
    b: b[index]
  }
})

console.log(final)

Upvotes: 2

Related Questions