skip to Main Content

Let’s say I have an array as follows:

[100,2,3,4,200,35,42,300,4,4,4,6,7,400,2]

And I want to create a map, like so:

{
 
   { key: 100,
     value: 2
   },
   { key: 100,
     value: 3
   }
   { key: 100,
     value: 4
   },

   { key: 200,
     value: 35
   },
   { key: 200,
     value: 42
   },

   { key: 300,
     value: 4
   },
   { key: 300,
     value: 4
   },
   { key: 300,
     value: 4
   },
   { key: 300,
     value: 6
   },
   { key: 300,
     value: 7
   },

   { key: 400,
     value: 2
   },

   
}

All the values in the bigger array are objects which have one or more fields.

I simulated the values with only one field using numbers 100, 200, 300, 400. You can call them flags. The rest of them being values with more than 1 field, of course.

My goal is to create map elements using the current flag with the items that follow it. For flag 300, the following elements are 4,4,4,6,7.

Here is what I tried:

let flagAndFollowingValues = new Map();
            let j=0;
            let followingElementsArray = [];
            console.log(itemsToBeCheckedArray[j]);
            for(let i=0; i<bigArray.length; i++){
                if(Object.keys(bigArray[i]).length > 1)
                {
                    followingElementsArray.push(bigArray[i]);
                }else if(Object.keys(bigArray[i]).length === 1){
                    if(i===0){
                        j++;
                        flagAndFollowingValues.set(itemsToBeCheckedArray[j], followingElementsArray);
                        followingElementsArray=[];
                    }else{
                        flagAndFollowingValues.set(itemsToBeCheckedArray[j], followingElementsArray);
                        followingElementsArray=[];
                    }
                }
            }

6

Answers


  1. First create a map logic, then filter out false entries:

    // Declare what your current key is, so we can save it when needed
    let currentKey = 0;
    
    // We just want to return the key and value
    // But not if the number is divisable by 100
    let result = [100,2,3,4,200,35,42,300,4,4,4,6,7,400,2].map(
    number => {
    
      // Check if key or value
      if (number % 100 === 0){
        currentKey = number
        return false;
      }
      
      return {key: currentKey, value: number}
    
    }
    );
    
    // Remove false keys
    result = result.filter(entry => entry !== false)
    
    console.log(result)
    Login or Signup to reply.
  2. I guess the code is self-explanatory. Just iterate the array and either get a new key or add a value to the current key.

    const source = [100,2,3,4,200,35,42,300,4,4,4,6,7,400,2];
    
    const mapped = [];
    let key;
    for(const value of source){
      if(value % 100 === 0){
         key = value;
         continue;
      }
      mapped.push({key,value});
    }
    
    console.log(mapped);
    Login or Signup to reply.
  3. You can reduce the data by adding new groups to the end of the resulting array.

    1. Reduce the data
      1. If the value is a key, add it to the end of the accumulator
      2. Else, push the current value to the last group in the accumulator
    2. Flat-map each group of values into a sub-array of values (with their key)
    const
      input = [100, 2, 3, 4, 200, 35, 42, 300, 4, 4, 4, 6, 7, 400, 2],
      processData = (arr, keyPredicate) => arr
        .reduce((acc, n) => {
          if (keyPredicate(n)) acc.push({ key: n, values: [] });
          else acc[acc.length - 1].values.push(n);
          return acc;
        }, [])
        .flatMap(({ key, values }) => values.map(value => ({ key, value }))),
      processed = processData(input, n => n >= 100);
    
    console.log(processed);
    .as-console-wrapper { top: 0; max-height: 100% !important; }
    Login or Signup to reply.
  4. Your proposed structure is useless, what you probably want is a map like

    100 => [ 2, 3, 4 ]
    200 => [ 35, 42 ]
    

    etc

    let a = [100,2,3,4,200,35,42,300,4,4,4,6,7,400,2]
    
    let m = new Map()
    let key = null
    
    for (let x of a)
        if (x % 100 === 0)
            key = x
        else if (m.has(key))
            m.get(key).push(x)
        else
            m.set(key, [x])
    
    console.log([...m])
    Login or Signup to reply.
  5. Another reduce() option using a single flag instead of if/else/map’s


    1. If the current value if larger then 100, set flag to that value
    2. Otherwise, add a new object to the array, with flag as key and the current value as the value.
    const data = [100,2,3,4,200,35,42,300,4,4,4,6,7,400,2];
    let flag = null;
    
    const result = data.reduce((p, c, i) => {
        if (c >= 100) {
            flag = c;
        } else {
            p.push({ key: flag, value: c });         
        }
        return p;
    }, []);
    
    console.log(result);
    Login or Signup to reply.
  6. If your flag is a multiple of 100, in that case it will work

    let flagObj = {};
    const data = [100,2,3,4,200,35,42,300,4,4,4,6,7,400,2];
    const res = data.reduce((acc, val, index)=> {
        let flag = val % 100;
        if(flag === 0 ){
            flagObj[val] = val;
        } else{
        let allFlags = Object.keys(flagObj);
        if(allFlags[allFlags.length-1]){
            let key = allFlags[allFlags.length -1]
            acc.push({
                key,
                value: val,
            });
        }
        }
        return acc;
    },[]);
    console.log('result>>>>>', res);
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search