Home > front end >  New Map from JSON data with unique values
New Map from JSON data with unique values

Time:04-30

I'm trying to create a new map of [key:value] as [trait_type]:[{values}] So taking the below data it should look like:


    [Hair -> {"Brown", "White-Blue"}, 
     Eyes -> {"Green", "Red"}
    ]

Heres my json obj

    [
        {
          "name":"Charlie",
          "lastname":"Gareth",
          "date":1645462396133,
          "attributes":[
             {
                "trait_type":"Hair",
                "value":"Brown"
             },
             {
                "trait_type":"Eyes",
                "value":"Red"
             }
          ]
        },
        {
          "name":"Bob",
          "lastname":"James",
          "date":1645462396131,
          "attributes":[
             {
                "trait_type":"Hair",
                "value":"White-Blue"
             },
             {
                "trait_type":"Eyes",
                "value":"green"
             }
          ]
        }
        ];

To note: I'm also trying to make it the values unique so If I have 2 people with red eyes the value would only ever appear once.

This is what I have so far, kind of works but in the console window the values come out as a char array.


    let newData = data.map((item) =>
        item.attributes.map((ats) => {
            return { [ats.trait_type]: [...ats.value] };
        })
    );
    newData.map((newItem) => console.log(newItem));

CodePudding user response:

You could take an object and iterate the nested data with a check for seen values.

const
    data = [{ name: "Charlie", lastname: "Gareth", date: 1645462396133, attributes: [{ trait_type: "Hair", value: "Brown" }, { trait_type: "Eyes", value: "Red" }] }, { name: "Bob", lastname: "James", date: 1645462396131, attributes: [{ trait_type: "Hair", value: "White-Blue" }, { trait_type: "Eyes", value: "green" }] }],
    result = data.reduce((r, { attributes }) => {
        attributes.forEach(({ trait_type, value }) => {
            r[trait_type] ??= [];
            if (!r[trait_type].includes(value)) r[trait_type].push(value);
        })
        return r;
    }, {});

console.log(result);

CodePudding user response:

try this

const extractTrait = data =>
  data.flatMap(d => d.attributes)
  .reduce((res, {
      trait_type,
      value
    }) => {
      return {
        ...res,
        [trait_type]: [...new Set([...(res[trait_type] || []), value])]
    }
  }, {})


const data = [{
    "name": "Charlie",
    "lastname": "Gareth",
    "date": 1645462396133,
    "attributes": [{
        "trait_type": "Hair",
        "value": "Brown"
      },
      {
        "trait_type": "Eyes",
        "value": "Red"
      }
    ]
  },
  {
    "name": "Bob",
    "lastname": "James",
    "date": 1645462396131,
    "attributes": [{
        "trait_type": "Hair",
        "value": "White-Blue"
      },
      {
        "trait_type": "Eyes",
        "value": "green"
      }
    ]
  }
];

console.log(extractTrait(data))

  • Related