Mapping key and value to new keys in Javascript - javascript

Array of dictionaries should be converted simpler form.
data = [{A:1},{B:2},{C:3}]
data = {A: 1, B: 2}
data = ["0":{ A : 1, B : 2 , C : 3}]
Both are completely different datasets. I'm trying to map it also like below format.
The above should become like
data = [
{
name: "A",
y: 1
},
{
name: "B",
y: 2
},
{
name: "C",
y: 3
}
];
I tried this following approach but it's wrong
name = {}
data.forEach(function(k,x){
return name['name'] = k , name["y"] = x
})
Please suggest me a better approach.

map each object's entries to extract the key and the value, and return an object with name and y keys:
const data = [{A:1},{B:2},{C:3}]
const output = data.map(item => {
const [name, y] = Object.entries(item)[0];
return { name, y };
});
console.log(output);

If the keys (A, B, etc) are guaranteed to be unique throughout the array, then everything becomes simpler.
const data = [{A:1},{B:2},{C:3}];
const merged = Object.assign({}, ...data);
const newData = Object.entries(merged)
.map(([name, y]) => ({ name, y }));
console.log(newData);
However, if the keys aren't guaranteed unique, then refer to CertainPerformance's answer.

you can implement like this
var data = [{A:1},{B:2},{C:3}];
var reformattedArra = data.map(obj => {
let val = {};
val.name = Object.keys(obj)[0];
val.y = obj[Object.keys(obj)[0]];
return val;
})
console.log(JSON.stringify(reformattedArra));

I would say, use Object.keys() which is widly supported
let data = [{A:1},{B:2},{C:3}];
data = Object.assign({}, ...data);
data = Object.keys(data).map(key => ({ name: key, y: data[key] }));
console.log(data);

You yould could chekc the data format and if it is not an array, build one and reduce the array by taking the objetcs and create for each key/value a new object for the result set.
function simple(data) {
return (Array.isArray(data) ? data : [data]).reduce((r, o) => [...r, ...Object.entries(o).map(([name, y]) => ({ name, y }))], []);
}
console.log(simple([{ A: 1 }, { B: 2 }, { C: 3, D: 4 }]));
console.log(simple({ A: 1, B: 2 }));
.as-console-wrapper { max-height: 100% !important; top: 0; }

Related

Js obj with key name defined by Object.keys

var c = {
'aa-bb': [{ a: 1, v: 2}],
'cc-xz': [{ c: 2}]
}
console.log(Object.keys(c))
I need to create an object, whose keys (the name) must be from Object.keys.
For each key name an object of type array must be defined as below.
Can you give me a hand?
result:
const res = {
'aa-bb': Array(number).fill(0),
'cc-xz': Array(number).fill(0)
};
var c = {
'aa-bb': [{
a: 1,
v: 2
}],
'cc-xz': [{
c: 2
}]
}
const keys = Object.keys(c);
let res = {},
number = 5;
keys.forEach(key => res[key] = Array(number).fill(0));
console.log(res);
Map the keys, and create pairs of [key, array], and convert back to an object using Object.fromEntries():
const fn = (obj, arrLengh) =>
Object.fromEntries(
Object.keys(obj)
.map(key => [key, Array(arrLengh).fill(0)])
);
const c = {"aa-bb":[{"a":1,"v":2}],"cc-xz":[{"c":2}]};
const result = fn(c, 5);
console.log(result);

FInd duplicates withtin array based on certain keys using lodash?

I have an array like this
let data = [{x:1,y:2,z:3},{x:1,y:2,z:3},{x:1,y:2,z:4},{x:11,y:2,z:3}]
Now I want to get only those items whose x,y,z values are the same.so expected output should be
{x:1,y:2,z:3}
Because {x:1,y:2,z:3} has duplicate values but rest of them not so I don't want to get rest of them because they do not have any duplicates. Please tell me how can I achieve this?
For lodash 4.17.15,
You can first use _.uniqWith and _.isEqual to find the unique values.
_.uniqWith(data, _.isEqual); // [{x:1,y:2,z:3},{x:1,y:2,z:4},{x:11,y:2,z:3}]
Then use _.difference to remove the unique values from the array, leaving just the duplicates
_.difference(data, _.uniqWith(data, _.isEqual)); // [{x:1,y:2,z:3}]
let data = [{x:1,y:2,z:3},{x:1,y:2,z:3},{x:1,y:2,z:4},{x:11,y:2,z:3},{x:11,y:2,z:3}]
function filterDuplicates(data) {
let dic = {};
data.forEach(obj => {
let strObj = JSON.stringify(obj, Object.keys(obj).sort());
if(strObj in dic) {
++dic[strObj];
return;
}
dic[strObj] = 0;
})
return Object.entries(dic).filter(([key, value]) => value > 0).map(([el]) => JSON.parse(el));
}
console.log(filterDuplicates(data));
Build an object to track the duplicates and use Object.values and filter
let data = [
{ x: 1, y: 2, z: 3 },
{ x: 1, y: 2, z: 3 },
{ x: 1, y: 2, z: 4 },
{ x: 11, y: 2, z: 3 },
];
const all = {};
data.forEach(({ x, y, z }) => {
const key = `x${x}y${y}z${z}`;
all[key] = key in all ? { x, y, z } : null;
});
const res = Object.values(all).filter(Boolean);
console.log(res);

Collecting indexed statisticts from list of objects in JS

So I have a list of objects, ex.
var data = [{a: 'data1', b: 'subdata1'}, {a: 'data2', b: 'subdata2'}, {a: 'data1', b: 'subdata3'}, {a: 'data1', b: 'subdata1'}]
(note the objects have other attributes too)
I'm looking to extract some condensed details of this list with a result:
[{type: 'data1', list: [{subtype: 'subdata1', count: 2}, {subtype: 'subdata3', count: 1}]}, {type: 'data2', list: [{subtype: 'data2', count: 1}]}]
I have been able to count the type (or subtype) with reduce:
data.reduce((lst, item) => { lst[item.type] = lst[item.type] + 1 || 1; return lst; }, {});
but, this isn't exactly the structure or complete detail I'm looking to achieve. I can obviously do the work manually with a for loop, but I'm hoping to understand map, reduce, etc. better for a cleaner/simpler implementation.
You could create a nested lookup table, (a -> b -> count), then you can iterate over that and build the result:
const table = {};
for(const { a, b } of data) {
if(!table[a]) table[a] = {};
if(!table[a][b]) table[a][b] = 0;
table[a][b]++;
}
const result = Object.entries(table)
.map(([type, entries]) => ({ type, list: Object.entries(entries).map(([ subtype, count ]) => ({ subtype, count })), }));
Yes, one could write that as a functional chain:
const result = Object.entries(
data.reduce(
((table, { a, b }) => (table[a] || (table[a] = {}))[b] = (table[a][b] || 0) + 1, table),
{}
)
).map(([type, entries]) => ({
type,
list: Object.entries(entries).map(([ subtype, count ]) => ({ subtype, count })),
}));
But IMO thats less readable.

Rearrange dynamic Object to form a structured Object

I have an Object like this:
const val = {"abc":{"1":1, "2":6,"3":5},"def":{"1":3, "2":4,"3":8},"xyz":{"1":5, "2":6,"3":7}}
I want to transform the object data like below:
[{"abc":1,"def":3,"xyz":5},{"abc":6,"def":4,"xyz":6}, ...]
All the values are dynamic, any number of inner object may be there
I have tried like this:
const val = {"abc":{"1":1, "2":6,"3":5},"def":{"1":3, "2":4,"3":8},"xyz":{"1":5, "2":6,"3":7}}
let dataObj = {};
let secondArr = [];
let dataArr =[]
Object.entries(val).map(firstObj=>{
Object.entries(firstObj[1]).forEach(secondObj => {
dataObj={[firstObj[0]]:secondObj[1]};
secondArr.push(dataObj);
})
dataArr.push(secondArr)
})
console.log(dataArr)
Can anyone tell me a solution for this?
Thanks in advance
You could iterate the entries of the objects and take the inner keys as indices of the array with new objects with outer key and value.
var data = { abc: { 1: 1, 2: 6, 3: 5 }, def: { 1: 3, 2: 4, 3: 8 }, xyz: { 1: 5, 2: 6, 3: 7 } },
result = Object
.entries(data)
.reduce((r, [k, o]) => {
Object.entries(o).forEach(([i, v]) =>
Object.assign(r[i - 1] = r[i - 1] || {}, { [k]: v }));
return r;
}, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Reduce JavaScript Objects into Array of Formatted Objects

I have an array of objects in the format
{type: number, sub_type: number}
I need to sort them into an array of objects formatted like this
{
type_id: (type from at least one object in array above),
sub_types: [
(all sub types from objects in array above that match this type)
]
}
This is what I came up but I think there is a more efficient way. rawTypes is an array of objects in need of formatting, types ends up being the array of formatted objects.
const typeIds = [...new Set(rawTypes.map(val => val.type))];
const types = typeIds.map(val => ({type_id: val, sub_types: [] }));
rawTypes.forEach(obj => {
let typeIndex = types.reduce((accum, val, i) => val.type_id === obj.type ? i : accum, 0);
types[typeIndex].sub_types.push(obj.sub_type);
});
I think a better solution would use recursion but I can't think of how to do it.
Look at this approach
var data = [{type: 5, sub_type: 10}, {type: 5, sub_type: 11}, {type: 6, sub_type: 12}];
var obj = data.reduce((a, c) => {
var current = a[`type_id_${c.type}`];
if (current) {
current.sub_types.push(c.sub_type);
} else {
var key = `type_id_${c.type}`;
a = { ...a, ...{ [key]: {sub_types: [c.sub_type], 'key': c.type} } };
}
return a;
}, {});
var array = Object.keys(obj).map((k) => ({ 'type': obj[k].key, 'subtypes': obj[k].sub_types }));
console.log(array)
.as-console-wrapper {
max-height: 100% !important
}

Categories

Resources