Maramal
Maramal

Reputation: 3474

Convert and filter dynamic JSON returned object

I am not sure how to achieve this,

I have this object which is a returned JSON:

[
    { first_dynamic_property: 'something', second_dynamic_property: 'something else' },
    { first_dynamic_property: 'something 2', second_dynamic_property: 'something else 2' },
    { first_dynamic_property: 'something 3', second_dynamic_property: 'null' },
    { first_dynamic_property: 'something', second_dynamic_property: 'something else' },
]

And I want to convert this object into a new one like:

[
    { first_dynamic_property: 'something' },
    { first_dynamic_property: 'something 2' },
    { first_dynamic_property: 'something 3' },
    { second_dynamic_property: 'something else' }
]

If you look, the object filtered the repeated ones and converted the two-item into an one-item object. I don't remember how to achieve this. Do you know the best way to do this?

Thanks and regards.

Edit 1:

I used first_dynamic_property and second_dynamic_property because I don't know the key names or how many they are. They are generated dynamically.

Upvotes: 0

Views: 48

Answers (3)

Yaroslav Bigus
Yaroslav Bigus

Reputation: 678

here is universal code for transforming list of any objects:

const data = [
    { first_dynamic_property: 'something', second_dynamic_property: 'something else' },
    { first_dynamic_property: 'something 2', second_dynamic_property: 'something else 2' },
    { first_dynamic_property: 'something 3', second_dynamic_property: 'null' },
    { first_dynamic_property: 'something', second_dynamic_property: 'something else' },
];
const result = data.reduce((acc, item) => {
        return [...acc, ...Object.keys(item).map((key) => { return {[key]: item[key]} })];
  }, []
);
console.log(result[0]);

Hope this helps :)

UPDATE: if you need to show only unique elements, you can add counter map and filter data. Smth like this:

const values_counter = {};
const result = data.reduce((acc, item) => {
        return [...acc, ...Object.keys(item).map(key => { 
        values_counter[item[key]] = values_counter[item[key]] + 1 || 1;
      return {[key]: item[key]} })
    ];
  }, []
).filter(item => values_counter[item[Object.keys(item)[0]]] === 1);

Upvotes: 1

wander
wander

Reputation: 957

Updated according to new requirement:

let dataList = [
    { first_dynamic_property: 'something', second_dynamic_property: 'something else' },
    { first_dynamic_property: 'something 2', second_dynamic_property: 'something else 2' },
    { first_dynamic_property: 'something 3', second_dynamic_property: 'null' },
    { first_dynamic_property: 'something', second_dynamic_property: 'something else' },
]
let values = new Set();

let result = dataList.map(data => {
    let newData = {};
    for (let key in data) {
        let value = data[key];
        if (values.has(value)) continue;
        values.add(value);
        newData[key] = value;
        break;
    }
    return newData;
})

console.info(result)

Upvotes: 1

Adam
Adam

Reputation: 1754

You can use an object to store the prexisting keys and then a simple map function to iterate over these and return the new array.

let existingKeys = {};

const input = [
    { first_dynamic_property: 'something', second_dynamic_property: 'something else' },
    { first_dynamic_property: 'something 2', second_dynamic_property: 'something else 2' },
    { first_dynamic_property: 'something 3', second_dynamic_property: 'null' },
    { first_dynamic_property: 'something', second_dynamic_property: 'something else' },
];

let output = input.map(elem => {
    const {first_dynamic_property, second_dynamic_property} = elem;
    if(!(first_dynamic_property in existingKeys)){
        existingKeys[first_dynamic_property] = true;
        return {first_dynamic_property};
    } else if(!(second_dynamic_property in existingKeys)){
        existingKeys[second_dynamic_property] = true;
        return {second_dynamic_property};
    }
});

Upvotes: -1

Related Questions