根据嵌套对象键和值合并两个对象数组

Merge two arrays of objects based on nested object key and value

我有以下两个对象数组,我想将它们合并到一个数组中,但基于第一个数组的嵌套对象内的一些嵌套键和值。

这是我现在拥有的:

const variants = [{
    "name": "Name 1",
    "variationValues": {
        "P00003": "mappedValue1",
        "P00004": "mappedValue4",
    }
}, {
    "name": "Name 2",
    "variationValues": {
        "P00003": "mappedValue2"
    }
}, {
    "name": "Name 3",
    "variationValues": {
        "P00003": "mappedValue3"
    }
}]

const variationAttributes = [{
    "id": "P00003",
    "name": "Variant Name",
    "attributes": [{
        "name": "Variant Name 1",
        "description": "Variant Description 1",
        "attribute": "mappedValue1"
    }, {
        "name": "Variant Name 2",
        "description": "Variant Description 2",
        "attribute": "mappedValue2"
    }, {
        "name": "Variant Name 3",
        "description": "Variant Description 3",
        "attribute": "mappedValue3"
    }, {
        "name": "Variant Name 4",
        "description": "Variant Description 4",
        "attribute": "mappedValue4"
    }]
}, {
    "id": "P00004",
    "name": "Variant Name",
    "attributes": [{
        "name": "Variant Name 4",
        "description": "Variant Description 4",
        "attribute": "mappedValue4"
    }]
}]

这是预期的结果:

const result = [{
    "variants": [{
        "name": "Name 1",
        "variationValues": {
            "P00003": {
                "name": "Variant Name 1",
                "description": "Variant Description 1",
                "attribute": "mappedValue1"
            },
            "P00004": {
                "name": "Variant Name 4",
                "description": "Variant Description 4",
                "attribute": "mappedValue4"
            }
        }
    }, {
        "name": "Name 2",
        "variationValues": {
            "P00003": {
                "name": "Variant Name 2",
                "description": "Variant Description 2",
                "attribute": "mappedValue2"
            }
        }
    }, {
        "name": "Name 3",
        "variationValues": {
            "P00003": {
                "name": "Variant Name 3",
                "description": "Variant Description 3",
                "attribute": "mappedValue3"
            }
        }
    }]
}]

基本上应该归结为以下几点:

  1. variants.variationValues['P00003'] 映射到 variationAttributes.id
  2. variants.variationValues[value] 映射到 variationAttributes.attribute.attribute[value]

我尝试开始使用 map 和 reduce 方法,但我什至不确定从哪里开始最好。

任何建议将不胜感激,提前致谢!

以下代码按照您指定的方式组合两个数组:

// Data

const variants = [{"name":"Name 1","variationValues":{"P00003":"mappedValue1"}},{"name":"Name 2","variationValues":{"P00003":"mappedValue2"}},{"name":"Name 3","variationValues":{"P00003":"mappedValue3"}}];
const variationAttributes = [{"id":"P00003","name":"Variant Name","attributes":[{"name":"Variant Name 1","description":"Variant Description 1","attribute":"mappedValue1"},{"name":"Variant Name 2","description":"Variant Description 2","attribute":"mappedValue2"},{"name":"Variant Name 3","description":"Variant Description 3","attribute":"mappedValue3"}]}];

// Solution code

console.log( getMappedVariants() );

function getMappedVariants() {
    return variants.map((variant) => ({
        ...variant,
        variationValues: mapValuesToAttributes(variant.variationValues),
    }));
}

function mapValuesToAttributes(values) {
    const attributes = {};
    for (const id in values) attributes[id] = findAttribute(id, values[id]);
    return attributes;
}

function findAttribute(id, value) {
    const variation = variationAttributes.find((v) => v.id === id);
    const attribute = variation.attributes.find((a) => a.attribute === value);
    return attribute;
}

对于它的运动来说,这可以减少到一个单一的功能,但我认为这是仍然可读的最高压缩级别。

尽管如此,这里有一个具有相同结果的单一函数的可憎之处:

const variants = [{"name":"Name 1","variationValues":{"P00003":"mappedValue1"}},{"name":"Name 2","variationValues":{"P00003":"mappedValue2"}},{"name":"Name 3","variationValues":{"P00003":"mappedValue3"}}];
const variationAttributes = [{"id":"P00003","name":"Variant Name","attributes":[{"name":"Variant Name 1","description":"Variant Description 1","attribute":"mappedValue1"},{"name":"Variant Name 2","description":"Variant Description 2","attribute":"mappedValue2"},{"name":"Variant Name 3","description":"Variant Description 3","attribute":"mappedValue3"}]}];

const getMappedVariants = () =>
    variants.map((variant) => ({
        ...variant,
        variationValues: Object.fromEntries(
            Object.entries(variant.variationValues).map(([id, value]) => [
                id,
                variationAttributes
                    .find((v) => v.id === id)
                    ?.attributes?.find?.((a) => a.attribute === value),
            ])
        ),
    }));

console.log(getMappedVariants());

这样:

const variants = 
  [ { name: 'Name 1', variationValues: { P00003: 'mappedValue1', Pxxxxx: 'mappedxxxxx', } } 
  , { name: 'Name 2', variationValues: { P00003: 'mappedValue2' } } 
  , { name: 'Name 3', variationValues: { P00003: 'mappedValue3' } } 
  ] 
const variationAttributes = 
  [ { id: 'P00003'
    , name: 'Variant Name'
    , attributes: 
      [ { name: 'Variant Name 1', description: 'Variant Description 1', attribute: 'mappedValue1' } 
      , { name: 'Variant Name 2', description: 'Variant Description 2', attribute: 'mappedValue2' } 
      , { name: 'Variant Name 3', description: 'Variant Description 3', attribute: 'mappedValue3' } 
    ] } 
  , { id: 'Pxxxxx'
    , name: 'Variant Name XXXXX'
    , attributes: 
      [ { name: 'Variant Name XXXXX', description: 'Variant Description XXXXX', attribute: 'mappedxxxxx' } 
    ] } 
  ] 


const result = [{}]

result[0].variants = variants.map(({name,variationValues})=>
  {
  let obj = { name, variationValues:{} }

  Object.entries(variationValues).forEach(([k,v]) => {
    let attr = variationAttributes.find(x=> x.id===k ).attributes.find(y=>y.attribute===v )
    obj.variationValues[k] = {...attr }
  })
  return ( obj )
  })

console.log( result )
.as-console-wrapper { max-height: 100% !important; top: 0 }