Jeremy P. Beasley
Jeremy P. Beasley

Reputation: 709

How to merge two objects based on varying indices

I've got two objects in an array returned from an API endpoint that exposes elected officials based on locale. One is offices and the other is officials. I need to understand how to merge these two objects into one that makes more sense.

{
  "offices": [
    {
      "name": "President of the United States",
      "officialIndices": [0]
    }, {
      "name": "Vice-President of the United States",
      "officialIndices": [1]
    }, {
      "name": "United States Senate",
      "officialIndices": [2, 3]
    }, {
      "name": "Governor",
      "officialIndices": [4]
    }
  ],
  "officials": [
    {
      "name": "Donald J. Trump"
    }, {
      "name": "Mike Pence"
    }, {
      "name": "Dianne Feinstein"
    }, {
      "name": "Kamala D. Harris"
    }, {
      "name": "Edmund G. Brown Jr.",
    }
  ]
}

My end goal would look like this:

[
  "officials": [
    {
      "name": "Donald J. Trump",
      "office": "President of the United States"
    }, {
      "name": "Mike Pence",
      "office": "Vice-President of the United States"
    }, {
      "name": "Dianne Feinstein",
      "office": "United States Senate"
    }, {
      "name": "Kamala D. Harris",
      "office": "United States Senate",
    }, {
      "name": "Edmund G. Brown Jr.",
      "office": "Governor"
    }
  ]
}

So this is my failed attempt.

var representatives = data;

function addOffice(name, indices){
  _.forEach(indices, function(value, key) {
    representatives.officials[key].office = name;
  });
}

_.forEach(representatives.offices, function(value, key) {
  // console.log("Office: '" + value.name + "' should be applied to officials " + value.officialIndices);
  addOffice(value.name, value.officialIndices);
});

// remove `offices` as it's now redundant
delete representatives.offices;

console.log(representatives);

Upvotes: 0

Views: 63

Answers (4)

ryeballar
ryeballar

Reputation: 30098

Here's a solution that uses flatMap to flatten the result of officials taken from using pick in an office's officialIndices. Lastly, we use map to transform the resulting value of all officials with their associated office.

var result = _.flatMap(data.offices, function(office) {
  return _(data.officials)
    .pick(office.officialIndices)
    .map(function(official) {
      return _(official)
        .pick('name')
        .set('office', office.name)
        .value();
    }).value();
});

var data = {
  "offices": [{
    "name": "President of the United States",
    "officialIndices": [0]
  }, {
    "name": "Vice-President of the United States",
    "officialIndices": [1]
  }, {
    "name": "United States Senate",
    "officialIndices": [2, 3]
  }, {
    "name": "Governor",
    "officialIndices": [4]
  }],
  "officials": [{
    "name": "Donald J. Trump"
  }, {
    "name": "Mike Pence"
  }, {
    "name": "Dianne Feinstein"
  }, {
    "name": "Kamala D. Harris"
  }, {
    "name": "Edmund G. Brown Jr.",
  }]
};

var result = _.flatMap(data.offices, function(office) {
  return _(data.officials)
    .pick(office.officialIndices)
    .map(function(official) {
      return _(official)
        .pick('name')
        .set('office', office.name)
        .value();
    }).value();
});

console.log(result);
body > div { min-height: 100%; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>

Upvotes: 0

Ruben Karapetyan
Ruben Karapetyan

Reputation: 469

you can do that like this:

obj.officials.map(function(item, i){
  var j = 0;
  for (j in obj.offices)
  {
    if (obj.offices[j].officialIndices.includes(i)) {
        break;
    }
  }
  return {
    "name": item.name,
    "office": obj.offices[j].name
  }
})

Upvotes: 0

Yonghoon Lee
Yonghoon Lee

Reputation: 2514

Use this function :

function addOffice(obj) {
  return {
    officials : obj.officials.map(function(official, idx){
      return {
        name : official.name,
        office : obj.offices.filter(function(office) {
          return office.officialIndices.indexOf(idx) > -1
        })[0].name
      }
    })
  }
}

Upvotes: 0

psycho
psycho

Reputation: 102

var offices = dataObj['offices'];
var officials = dataObj['officials'];
var mergedArray = {officials : []};

offices.forEach(function(obj, index) {
    var indices = obj['officialIndices'];
    indices.forEach(function(indice, ind) {
        var newObj = {};
        newObj['name'] = officials[indice]['name'];
        newObj['office'] = obj['name'];
        mergedArray['officials'].push(newObj);
    })
})

// mergedArray is your answer

Upvotes: 1

Related Questions