使用高阶函数合并相等的对象

时间:2018-05-23 12:30:03

标签: javascript typescript filter lodash

如果它们的值彼此相等,我想从数组中“合并”对象。

以下是一个例子:

"relations_entities": [
  {
    "relation": {
      "label": string,
      "inEntityId": string,
      "outEntityId": string,
      "proof": [
        {
          "text": string,
          "confidence": number,
        }
      ],
    },
    "entity": {
      "entityId": string,
      "label": string,
      "text": string,
    },
  },
  {
    "relation": {
      "label": string,
      "inEntityId": string,
      "outEntityId": string,
      "proof": [
        {
          "text": string,
          "confidence": number,
        }
      ],
    },
    "entity": {
      "entityId": string,
      "label": string,
      "text": string,
    },
  },
]

如果relations_entities[0].relation.labelrelations_entities[0].entity.label等于relations_entities[0].relation.labelrelations_entities[0].entity.label

然后我需要这个对象:

"relations_entities": [
  {
    "relation": {
      "label": string,
      "inEntityId": string,
      "outEntityId": string,
      "proof": [
        {
          "text": string,
          "confidence": number,
        },
        {
          "text": string,
          "confidence": number,
        }
      ],
    },
    "entity": {
      "entityId": string,
      "label": string,
      "text": string,
    },
  },
]

两个证明合并。

我尝试使用过滤器实现此行为,但我失去了理智。

也许使用lodash库?

有什么想法吗?

2 个答案:

答案 0 :(得分:0)

看看它:

let relations_entities = [
  {
    relation: {
      label: 'string',
      inEntityId: 'string',
      outEntityId: 'string',
      proof: [
        {
          text: 'string',
          confidence: 'number',
        }
      ],
    },
    entity: {
      entityId: 'string',
      label: 'string',
      text: 'string',
    },
  },
  {
    relation: {
      label: 'string',
      inEntityId: 'string',
      outEntityId: 'string',
      proof: [
        {
          text: 'string',
          confidence: 'number',
        }
      ],
    },
    entity: {
      entityId: 'string',
      label: 'string',
      text: 'string',
    },
  },
];

let merged = [];

relations_entities.forEach(el => {
  let found = false;  
  if (merged.length > 0) {
    merged.forEach(elM => {
      if (el.relation.label === elM.relation.label && !found) {
        elM.relation.proof = elM.relation.proof.concat(el.relation.proof);
        found = true;
      }
    });
  } 
  if (!found || merged.length === 0) {
    merged.push(el);
  }
});

console.log(merged);

答案 1 :(得分:0)

这是一个使用es6胖箭头功能的解决方案,这可以通过传入您想要检查的键来改进。如果您需要此功能,我不介意将其添加到您的答案中以获得完整性。

var relations_entities = [
  {
    "relation": {
      "label": 'a',
      "inEntityId": '123',
      "outEntityId": '123',
      "proof": [
        {
          "text": '123',
          "confidence": '123',
        }
      ],
    },
    "entity": {
      "entityId": '123',
      "label": '123',
      "text": '123',
    },
  },
  {
    "relation": {
      "label": 'b',
      "inEntityId": '321',
      "outEntityId": '321',
      "proof": [
        {
          "text": '321',
          "confidence": '321',
        }
      ],
    },
    "entity": {
      "entityId": '321',
      "label": '123',
      "text": '321',
    },
  },
  {
    "relation": {
      "label": 'c',
      "inEntityId": '321',
      "outEntityId": '321',
      "proof": [
        {
          "text": '321',
          "confidence": '321',
        }
      ],
    },
    "entity": {
      "entityId": '321',
      "label": '123',
      "text": '321',
    },
  },
  {
    "relation": {
      "label": 'b',
      "inEntityId": '321',
      "outEntityId": '321',
      "proof": [
        {
          "text": '321',
          "confidence": '321',
        }
      ],
    },
    "entity": {
      "entityId": '321',
      "label": '123',
      "text": '321',
    },
  }
]

const compareEntities = (oldEntities) => {
  // early breakout if there is just one element
  if (oldEntities.length === 0) {
    return oldEntities
  }
  
  // here we iterate through each of the passed in entities
  var newEntities = oldEntities.filter((entity, index, entities) => {
    // set the internal counter to 1 higher than the filtered counter
    // (the next object along)
    var i = index + 1
    const relationlabel = entity.relation.label
    const entityLabel = entity.entity.label

    // iterate through each remaining entity and remove from array if there is a match
    while (i < entities.length) {
      const relationLabelIsEqual = relationlabel === entities[i].relation.label
      const entityLabelIsEqual = relationlabel === entities[i].relation.label
      if (relationLabelIsEqual && entityLabelIsEqual) {
        i = index + 1
        return false
      }
      // if there is no match we just want to move onto the next entity
      ++i
    }
    // if we have iterated through all entities then there was no match
    // - return it into the new array
    return true
  })
  return newEntities
}

console.log(compareEntities(relations_entities))

您还可以使用repl i set up

进行游戏