Rename unknow key from json array in javascript - javascript

I been searching with no success, i would like to iterate over a json object but this have diferent names on keys, below my code
[{
"05115156165165" :{
"name":"John",
"Phone":"515555"
},
"111111111":{
"name":"John",
"Phone":"515555"
}
}]
So basically i need in the following way:
[{
"data" :{
"name":"John",
"Phone":"515555"
},
"data":{
"name":"John",
"Phone":"515555"
}
}]

You can use Object.values to retrieve values for unknwon keys and reduce to transform input array:
let input = [{
"05115156165165" :{
"name":"John",
"Phone":"515555"
},
"111111111":{
"name":"John",
"Phone":"5155557"
}
}];
let result = input.reduce((acc,cur)=> {
Object.values(cur).forEach(
obj => {acc.push({ data: obj });}
)
return acc;
},[]);
console.log(result);

The key is use Object.entries to iterate through all the keys in the object, which in this case it has only 1 that the name is unknown in every object.
const data = [{
"05115156165165": {
"name": "John1",
"Phone": "1111111"
},
"111111111": {
"name": "John2",
"Phone": "2222222"
}
}]
let result = []
data.forEach(d => {
for (const [key, value] of Object.entries(d)) {
result.push({
data: {
name: value.name,
Phone: value.Phone
}
})
}
})
console.log(result)

You can do something like this:
let data = [{
"05115156165165": {
"name": "John1",
"Phone": "1111111"
},
"111111111": {
"name": "John2",
"Phone": "2222222"
}
}]
let result = []
data.forEach(d => {
Object.keys(d).forEach(el => {
result.push({
data: d[el]
})
})
})
console.log(result)

Related

moving a key value pair out of an array

I am trying to move everything in the Array Results outside and into the original object
this is the object
{
"Name": "John",
"Results": [
{
"Type": "DB",
"Immediate_Action": "No",
}
]
}
It should look like this
{
"Name": "John",
"Type": "DB",
"Immediate_Action": "No",
}
What I have so far is this
const mapOscarResults = ({ data }) => {
return data.map(entry => {
let mapped = {...entry};
entry.Results.forEach(key => {
let Type = mapped[key.Type]
if (mapped[key]) {
mapped[key].push(entry.Results[key]);
} else {
mapped[key] = [entry.Results[key]];
}
});
return mapped;
});
};
You can simply spread the Results array into an Object.assign() call.
const input = { "Name": "John", "Results": [{ "Type": "DB", "Immediate_Action": "No", }, { "Another": "value" }] };
const { Results, ...refactored } = input;
Object.assign(refactored, ...Results);
console.log(refactored)
This code works for your example:
const { Results: results, ...rest } = {
"Name": "John",
"Results": [
{
"Type": "DB",
"Immediate_Action": "No",
}
]
}
const res = {...rest, ...results.reduce((prev, curr) => ({
...prev,
...curr
}), {})}
console.log(res)
But I don't know what you expect when the Results array has more than one element.
In that condition, if this code does not fill your needs, ask me to change it.
however, it will join first Result with index 0, you can expand it
const data = {
"Name": "John",
"Results": [
{
"Type": "DB",
"Immediate_Action": "No",
}
]
}
const mapOscarResults = (data) => {
for (let i in Object.keys(data)){
if (Array.isArray(data[Object.keys(data)[i]])){
newKey = data[Object.keys(data)[i]][0]
data = {... data, ...newKey}
delete data[Object.keys(data)[i]]
}
}
return data
};
console.log(mapOscarResults(data))

build array of object from tree object

I'm trying to get into javascript's built-in reduce function and with the help of that build objects inside array.
But you can use whatever function or method you want.
Expected output
[
{ 'team1': [14697807552, 6858384], '2021': [14697807552, 6858384], 'pepsi': [null, null], 'cola': [14697807552, 6858384] },
{ 'team2': [10268029152, 6922128], '2021': [10268029152, 6922128], 'pepsi': [null, 4800], 'cola': [10268029152, 6917328] },
]
What I tried to do
I created a function which takes array as an argument and calls reduce for each array's element.
function transform(arr, obj = {}) {
return arr.reduce((acc, item) => {
const newObj = {};
newObj[item.name] = item.metrics;
acc.push(newObj);
if (item.children) {
transform(item.children, newObj);
}
return acc;
}, []);
}
console.log(transform(arr))
<script>
const arr = [{
"name": "team1",
"metrics": [
14697807552,
6858384
],
"children": [{
"name": "2021",
"metrics": [
14697807552,
6858384
],
"children": [{
"name": "pepsi",
"metrics": [
null,
null
]
},
{
"name": "cola",
"metrics": [
14697807552,
6858384
]
}
]
}]
},
{
"name": "team2",
"metrics": [
10268029152,
6922128
],
"children": [{
"name": "2021",
"metrics": [
10268029152,
6922128
],
"children": [{
"name": "pepsi",
"metrics": [
null,
4800
]
},
{
"name": "cola",
"metrics": [
10268029152,
6917328
]
}
]
}]
}
]
</script>
But it gives me output that I don't want:
[
{ team1: [ 14697807552, 6858384 ] },
{ team2: [ 10268029152, 6922128 ] }
]
If you didn't understand my question or you have question, ask me. Thanks for paying attention!
The transform function doesn't do anything with the second argument obj, and so when you call transform recursively, newObj is not extended: this makes the recursive call losing any desired effect.
Instead of passing that second argument, you could use Object.assign to collect all objects that come back from recursion, and so merge them into one object:
const convert = arr =>
arr?.map(({name, metrics, children}) =>
Object.assign({[name]: metrics}, ...convert(children))) ?? [];
const arr = [{"name": "team1","metrics": [14697807552,6858384],"children": [{"name": "2021","metrics": [14697807552,6858384],"children": [{"name": "pepsi","metrics": [null,null]},{"name": "cola","metrics": [14697807552,6858384]}]}]},{"name": "team2","metrics": [10268029152,6922128],"children": [{"name": "2021","metrics": [10268029152,6922128],"children": [{"name": "pepsi","metrics": [null,4800]},{"name": "cola","metrics": [10268029152,6917328]}]}]}];
console.log(convert(arr));
Please realise that a property like '2021' is an index and will be ordered before other, non-index properties. Even if you print an object like { 'a': 2, '2021': 1 } you'll get the keys in opposite order for that same reason.
If the order of the object keys is important to you, then you should go for an array of pairs in stead of a plain object. Arrays are the structure of choice when you need order, and plain objects should be used when order is not essential.
I have found a bit different solution:)
It is longer than answer from #trincot but also works
const arr = [{"name": "team1","metrics": [14697807552,6858384],"children": [{"name": "2021","metrics": [14697807552,6858384],"children": [{"name": "pepsi","metrics": [null,null]},{"name": "cola","metrics": [14697807552,6858384]}]}]},{"name": "team2","metrics": [10268029152,6922128],"children": [{"name": "2021","metrics": [10268029152,6922128],"children": [{"name": "pepsi","metrics": [null,4800]},{"name": "cola","metrics": [10268029152,6917328]}]}]}];
const handleArr = (list, rez) => {
list.forEach((item) => {
rez[item.name] = item.metrics;
item.children && handleArr(item.children, rez);
});
};
const handle = (list) => {
const rezArr = [];
for (const item of list) {
const rezObj = { [item.name]: item.metrics };
item.children && handleArr(item.children, rezObj);
rezArr.push(rezObj);
}
return rezArr;
};
console.log(handle(arr));
This approahc returns a different result and uses all previous information to get a denormalization of the data.
const
flat = array => array.flatMap(({ name, metrics, children }) => children
? flat(children).map(q => ({ [name]: metrics, ...q }))
: { [name]: metrics }),
data = [{ name: "team1", metrics: [14697807552, 6858384], children: [{ name: "2021", metrics: [14697807552, 6858384], children: [{ name: "pepsi", metrics: [null, null] }, { name: "cola", metrics: [14697807552, 6858384] }] }] }, { name: "team2", metrics: [10268029152, 6922128], children: [{ name: "2021", metrics: [10268029152, 6922128], children: [{ name: "pepsi", metrics: [null, 4800] }, { name: "cola", metrics: [10268029152, 6917328] }] }] }],
result = flat(data);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

How to create JSON Object in JavaScript?

I have JSON like this :
{
"success":true,
"data":[
{
"id": 1,
"markname":"nama_penduduk",
"markvalue":"Vin Diesel"
},
{
"id": 2,
"markname":"umur_penduduk",
"markvalue":"20 Tahun"
},
{
"id": 3,
"markname":"keperluan_membuat_surat",
"markvalue":"Untuk uji coba surat"
}
]
}
I'm trying to create a JSON like this :
const newJSON = {
nama_penduduk: 'Vin Diesel',
umur_penduduk: '20 Tahun',
keperluan_membuat_surat: 'Untuk uji coba surat'
};
Code :
dataResult.map((value) => {
const markName = value.markname;
const markValue = value.markvalue;
res.status(200).json({
markName: markValue
});
});
Suppose I don't know how many data I have, how do I create this object in JavaScript?
You can use Array.reduce()
const dataResult = [{
"id": 1,
"markname": "nama_penduduk",
"markvalue": "Vin Diesel"
},
{
"id": 2,
"markname": "umur_penduduk",
"markvalue": "20 Tahun"
},
{
"id": 3,
"markname": "keperluan_membuat_surat",
"markvalue": "Untuk uji coba surat"
}
]
const newJSON = dataResult.reduce((acc, cur) => {
acc[cur.markname] = cur.markvalue;
return acc;
}, {});
console.log(newJSON);
Use reduce:
const myObject = dataResult.reduce((acc, curr) => {
curr[acc.markname] = acc.markvalue;
return curr;
}, {});
So yeah, we add acc.markname on the returned object. Pretty self explanatory :)

Assign to object within map

I'd like to assign to an object within an array map
Heres the array of objects I want to add to
const arr = [
{
"key": "Mike",
"ref": 11800
},
{
"key": "Raph",
"ref": 9339
},
{
"key": "Leo",
"ref": 2560
},
]
I want to add add a new property to the object called slug while I loop over it like below. Possibly map is not the right function to use here because ESLINT complains about assigning within the map.
arr.map((item) => {
...item,
item.slug = `${item.key.toLowerCase();}/${String(item.ref)}`
});
.map() returns a new array containing the results of calling provided function for each element, so you should assign it to the new variable:
const arr = [{
"key": "Mike",
"ref": 11800
},
{
"key": "Raph",
"ref": 9339
},
{
"key": "Leo",
"ref": 2560
},
]
const newArr = arr.map(item => ({
...item,
slug: `${item.key.toLowerCase()}/${String(item.ref)}`
}))
console.dir(newArr)
If you want to add something to existing objects within an array you should use a for loop or .forEach():
const arr = [{
"key": "Mike",
"ref": 11800
},
{
"key": "Raph",
"ref": 9339
},
{
"key": "Leo",
"ref": 2560
},
]
arr.forEach(item => {
item.slug = `${item.key.toLowerCase()}/${String(item.ref)}`
})
console.dir(arr)
When mutating an array, or perform operations with side-effects, you should use a for loop or the Array.prototype.forEach method. If you want to perform pure functional operations over an array, then use Array.prototype.filter, Array.prototype.map, etc.
If you want to set a new property on the existing array elements then do this:
const arr = [ { key: "Mike", ref: 11800 }, /*etc*/ ];
for( const e of arr ) {
e.slug = e.key.toLowerCase() + "/" + e.ref.toString();
}
If you want to generate a new array with new members, then do this:
const arr = [ { key: "Mike", ref: 11800 }, /*etc*/ ];
// Note the parentheses within `map` to avoid ambiguous syntax:
const newArr = arr.map( e => ( { slug: e.key.toLowerCase() + "/" + e.ref.toString() } ) );
console.log( newArr ); // [ { slug: "mike/11800" } ]
Alternatively, to copy over all properties and then add new properties use Object.assign:
const arr = [ { key: "Mike", ref: 11800 }, /*etc*/ ];
const newArr = arr.map( e => Object.assign( {}, e, { slug: e.key.toLowerCase() + "/" + e.ref.toString() } ) );
console.log( newArr ); // [ { key: "Mike", ref: 11800, slug: "mike/11800" } ]

Build array from another array if some key are identical using JavaScript

I have an array of data. Some of the key in the array are same. I would like to create a new array based on the key and add the other data.
This is my array
var myObjOne = [
{
"name":"John",
"id":1,
"car":"maruti"
},
{
"name":"John",
"id":2,
"car":"wolks"
},
{
"name":"John",
"id":3,
"car":"bmw"
},
{
"name":"Peter",
"id":4,
"car":"alto"
},
{
"name":"Peter",
"id":5,
"car":"swift"
}
];
I would like to convert the array in to the below format.
var myObj = [
{
"name":"John",
"items": [
{ "id":1, "car":"maruti" },
{ "id":2, "car":"wolks" },
{ "id":3, "car":"bmw" }
]},
{
"name":"Peter",
"items": [
{ "id":4, "car":"alto" },
{ "id":5, "car":"swift" },
]
}
];
I am working on a node environment.
You can create an object using Array#reduce first which maps name with items, and then create the final array by looping over the intermediate map using a for...of loop:
var source = [{"name":"John","id":1,"car":"maruti"},{"name":"John","id":2,"car":"wolks"},{"name":"John","id":3,"car":"bmw"},{"name":"Peter","id":4,"cars":"alto"},{"name":"Peter","id":5,"cars":"swift"}];
const map = source.reduce((acc, {name, ...obj}) => {
if (!acc[name]) {
acc[name] = [];
}
acc[name].push(obj);
return acc;
}, {});
const result = [];
for (let[name, items] of Object.entries(map)) {
result.push({name, items});
}
console.log(result);
Array.reduce is at rescue.This method accepts an accumulator and current
item. Check in the accumulator if there exist an object where the value of name property is John or Peter
var myObjOne = [{
"name": "John",
"id": 1,
"car": "maruti"
},
{
"name": "John",
"id": 2,
"car": "wolks"
},
{
"name": "John",
"id": 3,
"car": "bmw"
},
{
"name": "Peter",
"id": 4,
"car": "alto"
},
{
"name": "Peter",
"id": 5,
"car": "swift"
}
];
var newObj = myObjOne.reduce(function(acc, curr, currIndex) {
// using findIndex to check if there exist an object
// where the value of the name property is John, Peter
// if it exist it will return the index else it will return -1
let ifNameExist = acc.findIndex(function(item) {
return item.name === curr.name;
})
// if -1 then create a object with name and item property and push
// it to the accumulator
if (ifNameExist === -1) {
let nameObj = {};
nameObj.name = curr.name;
nameObj.items = [];
nameObj.items.push({
id: curr.id,
car: curr.car
})
acc.push(nameObj)
} else {
// if such an object already exist then just update the item array
acc[ifNameExist].items.push({
id: curr.id,
car: curr.car
})
}
return acc;
}, []);
console.log(newObj)
Use .reduce to group by name, and use .find inside the reducer to find if the matching name has already been added:
const input=[{"name":"John","id":1,"car":"maruti"},{"name":"John","id":2,"car":"wolks"},{"name":"John","id":3,"car":"bmw"},{"name":"Peter","id":4,"cars":"alto"},{"name":"Peter","id":5,"cars":"swift"}]
const output = input.reduce((a, { name, ...item }) => {
const foundNameObj = a.find(nameObj => nameObj.name === name);
if (foundNameObj) foundNameObj.items.push(item);
else a.push({ name, items: [item] });
return a;
}, []);
console.log(output);

Categories