javascriptobjectkeykey-valuecreation

How does one create an object based on the precedence of another object's key order?


I have an object like this -

const obj = {
    'veh1': 'Car',
    'veh2': 'Bicycle',
    'veh3': 'Truck',
    'wheels1': '4',
    'wheels2': '2',
    'wheels3': '8'
}

I want an object which have entries mapped like- veh1 to wheels1, veh2 to wheels2, veh3 to wheels3 and so on The resultant object should be like this-

const result = {
    'Car': '4',
    'Bicycle': '2',
    'Truck': '8'
}

I know, we can do it directly like this -

{
   [obj.veh1]: obj.wheels1,
   [obj.veh2]: obj.wheels2,
   [obj.veh3]: obj.wheels3
}

But what will be the better way? The number of entries can be any number 'n'.

How can I attain this through javascript?


Solution

    1. Create entries (key value pairs) from the provided object.
    2. Sort the entries by each of an entry's key.
    3. Finally create a new objects from the upper (or left) as well the lower (or right) half of the before sorted entries.

    function localeCompare(a, b) {
      return (a.localeCompare && b.localeCompare
        && a.localeCompare(b))
        || (((a < b) && -1) || ((a > b) && 1) || 0);
    }
    
    function compareEntriesByKey(entryA, entryB) {
      return localeCompare(entryA[0], entryB[0]);
    }
    
    function createKeyValuePairFromSortedEntryHalfs(obj, $, idx, entries) {
      if (((idx + 1) % 2) === 0) {
     
        const keyIdx = ((idx - 1) / 2);
        const valueIdx = (keyIdx + Math.floor(entries.length / 2));
    
        const key = entries[keyIdx][1];
        const value = entries[valueIdx][1];
    
        obj[key] = value;
      }
      return obj;
    }
    
    
    const obj = {
      'wheels3': '8',
      'veh3': 'Truck',
      'wheels1': '4',
      'veh1': 'Car',
      'wheels2': '2',
      'veh2': 'Bicycle',
    }
    const result = Object
      // (1) create entries (key value pairs) from the provided object.
      .entries(obj)
      // (2) sort the entries by each of an entry's key.
      .sort(compareEntriesByKey)
      // (3) finally create a new objects from the upper (or left) as
      //     well the lower (or right) half of the before sorted entries.
      .reduce(createKeyValuePairFromSortedEntryHalfs, {});
    
    console.log('result :', result);
    
    console.log('obj', obj);
    console.log(
      'Object.entries(obj).sort(compareEntriesByKey)',
      Object.entries(obj).sort(compareEntriesByKey)
    );
    
    console.log(
      'proof of being a generic approach...', `
      Object.entries({
        'foo-biz': 'biz',
        'x': 111,
        'foo-baz': 'baz',
        'y': 222,
        'foo-bar': 'bar',
        'z': 333,
      }).sort(
        compareEntriesByKey
      ).reduce(
        createKeyValuePairFromSortedEntryHalfs,
        {}
      ) =>`, Object.entries({
        'foo-biz': 'biz',
        'x': 111,
        'foo-baz': 'baz',
        'y': 222,
        'foo-bar': 'bar',
        'z': 333,
      }).sort(
        compareEntriesByKey
      ).reduce(
        createKeyValuePairFromSortedEntryHalfs,
        {}
      )
    );
    .as-console-wrapper { min-height: 100%!important; top: 0; }