aftab
aftab

Reputation: 693

How to use reduce and map new object to resolve duplciate values in JS?

i have response coming from backend now forming new object , Also trying to implement logic if there is duplicate clientname build object as i have in expected result ? Am i missing something in reduce method its not taking spread operator ? what is correct approach to achieve this task ?

main.js

const data = [
  {
      clientname: "SDK_AETNA",
      preferencename: "apiKey",
      preferencevalue: "a4ddaf8d-b74e-4158-87fb"
  }, 
  {
      clientname: "SDK_CLOVER",
      preferencename: "apiKey",
      preferencevalue: "9e8323b3-93b3-4bc9-a02d"
  }, 
  {
      clientname: "SDK_RMN",
      preferencename: "apiKey",
      preferencevalue: "60470ae8-ac70-429c-806"
  }, {
      clientname: "SDK_RMN",
      preferencename: "plapiKey",
      preferencevalue: "7c4f6820-e799-410c-876"
  }
];

function mapData(data)
{
  var tempArray= [];
  var myOrderedArray = data.reduce(function (accumulator, currentValue) 
  {
    var newObj = {};
    newObj.clientName = accumulator.clientname;
    newObject.apiKey = accumulator.preferencevalue;
    tempArray.push(newObj);
    
    if (accumulator.clientname === currentValue.clientname) 
    {
      if (newObj.clientName === currentValue.clientname)
      {
        ...newObj,
          plapikey: currentValue.preferencevalue
      }
    }
    
    return tempArray
  }, []);


}

mapData(data);

const data = [{
        clientname: "SDK_AETNA",
        preferencename: "apiKey",
        preferencevalue: "a4ddaf8d-b74e-4158-87fb"
    }, {
        clientname: "SDK_CLOVER",
        preferencename: "apiKey",
        preferencevalue: "9e8323b3-93b3-4bc9-a02d"
    }, {
        clientname: "SDK_RMN",
        preferencename: "apiKey",
        preferencevalue: "60470ae8-ac70-429c-806"
    }, {
        clientname: "SDK_RMN",
        preferencename: "plapiKey",
        preferencevalue: "7c4f6820-e799-410c-876"
    }];

    function mapData(data){
      var tempArray= [];
     var myOrderedArray = data.reduce(function (accumulator, currentValue) {
     var newObj = {};
     newObj.clientName = accumulator.clientname;
     newObject.apiKey = accumulator.preferencevalue;
     tempArray.push(newObj);
      if (accumulator.clientname === currentValue.clientname) {
          if (newObj.clientName === currentValue.clientname){
              ...newObj,
                plapikey: currentValue.preferencevalue
          }

       }
      return tempArray
    }, [])


    }

    mapData(data);

expected result

 [{
    clientname: "SDK_AETNA",
    apiKey: "a4ddaf8d-b74e-4158-87fb"
}, {
    clientname: "SDK_CLOVER",
    apiKey: "9e8323b3-93b3-4bc9-a02d"
}, {
    clientname: "SDK_RMN",
    apiKey: "60470ae8-ac70-429c-806",
    plapikey: "7c4f6820-e799-410c-876"
}];

Upvotes: 0

Views: 163

Answers (3)

Harry Chang
Harry Chang

Reputation: 389

Just pure reduce from the original data. No extra object is needed.

function mapData(data) {
  return data.reduce((acc, curr) => {
    let newAcc = [...acc];
    let targetIdx = newAcc.findIndex(v => v.clientname === curr.clientname);
    if (targetIdx === -1) {
      newAcc = [...newAcc, { clientname: curr.clientname }];
      targetIdx = newAcc.length - 1;
    }
    return [
      ...newAcc.slice(0, targetIdx),
      { ...newAcc[targetIdx], [curr.preferencename]: curr.preferencevalue },
      ...newAcc.slice(targetIdx + 1),
    ];
  }, []);
}

const data = [
  {
    clientname: 'SDK_AETNA',
    preferencename: 'apiKey',
    preferencevalue: 'a4ddaf8d-b74e-4158-87fb',
  },
  {
    clientname: 'SDK_CLOVER',
    preferencename: 'apiKey',
    preferencevalue: '9e8323b3-93b3-4bc9-a02d',
  },
  {
    clientname: 'SDK_RMN',
    preferencename: 'apiKey',
    preferencevalue: '60470ae8-ac70-429c-806',
  },
  {
    clientname: 'SDK_RMN',
    preferencename: 'plapiKey',
    preferencevalue: '7c4f6820-e799-410c-876',
  },
];

console.log(mapData(data));

Upvotes: 0

Eddie D
Eddie D

Reputation: 1120

When you initialize reduce, you pass it a call back function in the format

function callback(accumilator, value, index, array)

the second parameter is the initial value of the accumulator. In your case it's [].

It then loops over the method and applies the logic. At the end of the function, accumulator = the return value of your callback.

for example :

var myArray = [2, 4, 6, 8];
var myObject = {};

function myCallback(accumalator, value, index, arr)
{
  accumalator[value] = value * 2;
  return accumalator;
}

myArray.reduce(myCallback, myObject);

console.log(myObject);

// Now wityh duplicate filtering

var filteredArr = [];
function FilterDups(accumalator, value, index, arr)
{
  if (!accumalator[value]) 
  {
    accumalator[value] = true;
    filteredArr.push(value);
  }
  
  return accumalator;
}

var duplicateData = [ 2, 2, 3, 4, 5, 6, 6, 6 ]
duplicateData.reduce(FilterDups, {});
console.log(filteredArr)

You're treating accumalator as if it were a value in your array when it's an empty array to begin with. Secondly, You're comparison is off

Upvotes: 0

slider
slider

Reputation: 12990

When you reduce, use an object (or a Map) that maps from clientname to your desired object so that you can update it appropriately when you find a duplicate. Then, you can get your final array with Object.values:

const data = [{
  clientname: "SDK_AETNA",
  preferencename: "apiKey",
  preferencevalue: "a4ddaf8d-b74e-4158-87fb"
}, {
  clientname: "SDK_CLOVER",
  preferencename: "apiKey",
  preferencevalue: "9e8323b3-93b3-4bc9-a02d"
}, {
  clientname: "SDK_RMN",
  preferencename: "apiKey",
  preferencevalue: "60470ae8-ac70-429c-806"
}, {
  clientname: "SDK_RMN",
  preferencename: "plapiKey",
  preferencevalue: "7c4f6820-e799-410c-876"
}];

const result = Object.values(data.reduce((acc, {clientname, preferencename, preferencevalue}) => {
  acc[clientname] = acc[clientname] || {clientname};
  acc[clientname][preferencename] = preferencevalue;
  return acc;
}, {}));

console.log(result);

Upvotes: 3

Related Questions