How to convert json object keys into different arrays removing the duplicate - javascript

I'm having the JSON like this i need to group this JSON with all the keys in JSON object and value should in array (excluding duplicates).
var people = [
{sex:"Male", name:"Jeff"},
{sex:"Female", name:"Megan"},
{sex:"Male", name:"Taylor"},
{sex:"Female", name:"Madison"}
];
My output should be like
{"sex":["Male","Female"],"name":["Jeff","Megan","Taylor","Madison"]}
how we can able to achieve this

function getValues(array) {
var result = {};
array.forEach(obj => {
Object.keys(obj).forEach(key => {
if(!Array.isArray(result[key]))
result[key] = [];
result[key].push(obj[key]);
})
})
return result;
}

You could use the Array.reduce() method to transform your array into a single object:
var people = [
{sex:"Male", name:"Jeff"},
{sex:"Female", name:"Megan"},
{sex:"Male", name:"Taylor"},
{sex:"Female", name:"Madison"}
];
const transformed = people.reduce((acc, e) => {
Object.keys(e).forEach((k) => {
if (!acc[k]) acc[k] = [];
if (!acc[k].includes(e[k])) acc[k].push(e[k]);
});
return acc;
}, {});
console.log(transformed);
If for one of the object keys (sex or name in this case) a value array does not exist, it is created. Before a value is pushed into any of the value arrays, it is verified that it is not already present in that array.

Related

Merge Javascript Objects WITH Same Key AND Include Duplicate Values WHERE Key Matches

I am trying to merge some JSON data sets BY key value WHILE including duplicate values WHERE the key matches.
I have tried this quite a bit now but can't seem to produce the object that I need.
Object 1
[
{"userId":"1",
"email":"email1#gmail.com"
},
{"userId":"2",
"email":"email2#gmail.com"
}
]
Object 2
[
{"id":"1abc",
"listingId":"4def",
"userId":"2"
},
{"id":"2abc",
"listingId":"2def",
"userId":"1"
},
{"id":"3abc",
"listingId":"3def",
"userId":"2"
}
]
I need to merge these objects in a way that looks like this:
Desired Output
[
{"id":"1abc",
"listingId":"4def",
"userId":"2",
"email":"email2#gmail.com"
},
{"id":"2abc",
"listingId":"2def",
"userId":"1",
"email":"email1#gmail.com"
},
{"id":"3abc",
"listingId":"3def",
"userId":"2",
"email":"email2#gmail.com"
}
]
Problems I am Experiencing
I am able to merge the data sets successfully using a function that looks like this:
function merge(a, b, key) {
function x(a) {
a.forEach(function (b) {
if (!(b[key] in obj)) {
obj[b[key]] = obj[b[key]] || {};
array.push(obj[b[key]]);
}
Object.keys(b).forEach(function (k) {
obj[b[key]][k] = b[k];
});
});
}
var array = [],
obj = {};
x(a);
x(b);
return array;
}
https://stackoverflow.com/a/35094948/1951144
But it produces results that look like this:
[
{"id":"1abc",
"listingId":"4def",
"userId":"2",
"email":"email2#gmail.com"
},
{"id":"2abc",
"listingId":"2def",
"userId":"1",
"email":"email1#gmail.com"
}
]
Is there a way to use the above function WHILE keeping AND including the duplicate values where my keys match?
For each element in arr2, create a new element containing the props of the item from arr2, and the email of the corresponding entry in arr1.
let arr1 = [
{"userId":"1",
"email":"email1#gmail.com"
},
{"userId":"2",
"email":"email2#gmail.com"
}
];
let arr2 = [
{"id":"1abc",
"listingId":"4def",
"userId":"2"
},
{"id":"2abc",
"listingId":"2def",
"userId":"1"
},
{"id":"3abc",
"listingId":"3def",
"userId":"2"
}
];
let output = arr2.map(a2 => ({...a2, email: arr1.find(a1 => a1.userId === a2.userId)?.email}));
console.log(output);
This solution works even if the key isn't known yet. .flatMap() both arrays and pass in the desired key (in example it's "userId"). Use Object.entries() on each object so they will be an array of pairs.
[{A1: A1v}, {A2: A2v},...]
// into
[[A1, A1v], [A2, A2v],...]
.flatMap() the second array and on each iteration .flatMap() the first array. Then compare the given key ("userID") with the key of each object from the second array ("a") AND the value of that key and the value of the key of the object in the first array.
a === key && av === bv
If both criteria are meet then merge those objects and return it, otherwise...
? {...objA, ...objB}
return an empty array, which ultimately results to nothing since .flatMap() flattens one level of arrays.
: []
const arrA=[{userId:"1",email:"email1#gmail.com"},{userId:"2",email:"email2#gmail.com"}];const arrB=[{id:"1abc",listingId:"4def",userId:"2"},{id:"2abc",listingId:"2def",userId:"1"},{id:"3abc",listingId:"3def",userId:"2"}];
function masterKey(primary, key, secondary) {
let result = secondary.flatMap(objB => Object.entries(objB).flatMap(([b, bv]) =>
primary.flatMap(objA => Object.entries(objA).flatMap(([a, av]) =>
a === key && av === bv ? {...objA, ...objB} : []))));
return result;
}
console.log(masterKey(arrA, "userId", arrB));

while pushing the data in to arrays, not added in order

enter image description here
i need to push the data one after another, but here i am getting to add in disorder like last added array in to first.
for (var key in data[tabName + scoreBreakDown]) {
var values = data[tabName + scoreBreakDown][key];
var staticData = values[0];
var obj = [];
obj.push(staticData.CompanyName);
obj.push(staticData.Country_ORIG);
for (var value in values) {
if (addHeader) {
headersArray.push(values[value].AspectName);
weightArray.push(values[value].ScoreWeight);
}
obj.push(values[value].SPESGScore_ORIG);
}
addHeader = false;
dataArray.push(obj);
}
You can use array.map to map through an array and transform it into a new array in order.
In this example, we are just multiplying each value by 3, but the transformation is arbitrary.
let loop = (arr) => {
return arr.map(item => {
return item*3
})
}
console.log(loop([1,2,3,4,5]))
If you want to loop through an object in order this way, you can use Object.keys() this will return an array of the keys in the object.
let loop = (obj) => {
return Object.keys(obj).map(item => {
return `${item}: ${obj[item]}`
})
}
let obj = {
first_name:"John",
last_name:"Doe",
age:23
}
console.log(loop(obj))
So instead of using a for loop and an if statement to check a condition and push the data to the array after each iteration, you can use something Array.filter() to remove entries you don't want to push, and return them in order.
data = [
{header:true, value:"item1"},
{header:false, value:"item2"},
{header:true, value:"item3"},
]
let array = data.filter(item => {return item.header}).map(item => {
return item.value
})
console.log(array)

Java script filter on array of objects and push result's one element to another array

I have a array called data inside that array I have objects.
An object structure is like this
{
id:1,
especial_id:34,
restaurant_item:{id:1,restaurant:{res_name:'KFC'}}
}
I want to pass a res_name eg:- KFC
I want an output as a array which consists all the especial_ids
like this
myarr = [12,23,23]
I could do something like this for that. But I want to know what is more elegant way to do this.
const data = [
{id:1,especial_id:6,restaurant_items:{id:5,res_name:'McDonalds'}},
{id:1,especial_id:8,restaurant_items:{id:5,res_name:'Kfc'}},
{id:1,especial_id:6,restaurant_items:{id:5,res_name:'Sunmeal'}},
{id:1,especial_id:6,restaurant_items:{id:5,res_name:'Kfc'}},
];
let temp = data.filter(element => element.restaurant_items.res_name == 'kfc')
let myArr = [];
temp.forEach(element=> myArr.push(element.especial_id));
console.log(myArr)//[8,6]
You can try this. It uses "Array.filter" and "Array.map"
var data = [
{id:1,especial_id:6,restaurant_items:{id:5,res_name:'McDonalds'}},
{id:1,especial_id:8,restaurant_items:{id:5,res_name:'Kfc'}},
{id:1,especial_id:6,restaurant_items:{id:5,res_name:'Sunmeal'}},
{id:1,especial_id:6,restaurant_items:{id:5,res_name:'Kfc'}},
];
function getEspecialIdsByName(name) {
return data.filter(d => d.restaurant_items.res_name.toLowerCase() == name.toLowerCase())
.map(d => d.especial_id)
}
console.log(getEspecialIdsByName('Kfc'))
console.log(getEspecialIdsByName('Sunmeal'))
You can reduce to push elements which pass the test to the accumulator array in a single iteration over the input:
const data = [
{id:1,especial_id:6,restaurant_items:{id:5,res_name:'McDonalds'}},
{id:1,especial_id:8,restaurant_items:{id:5,res_name:'Kfc'}},
{id:1,especial_id:6,restaurant_items:{id:5,res_name:'Sunmeal'}},
{id:1,especial_id:6,restaurant_items:{id:5,res_name:'Kfc'}},
];
console.log(
data.reduce((a, { especial_id, restaurant_items: { res_name }}) => {
if (res_name === 'Kfc') a.push(especial_id)
return a;
}, [])
);
Use Array.reduce
const data = [{id:1,especial_id:6,restaurant_items:{id:5,res_name:'McDonalds'}},{id:1,especial_id:8,restaurant_items:{id:5,res_name:'Kfc'}},{id:1,especial_id:6,restaurant_items:{id:5,res_name:'Sunmeal'}},{id:1,especial_id:6,restaurant_items:{id:5,res_name:'Kfc'}}];
let result = data.reduce((a,c) => {
if(c.restaurant_items.res_name === 'Kfc') a.push(c.especial_id);
return a;
},[]);
console.log(result);

JavaScript or Lodash find objects by key

In an array of objects with diff keys, how do I find objects by key using ES6 or Lodash?
const arr = [{a:2}, {b:3}, {fred:10}]
I want the result to be:
=> [{a:2}, {fred:10}]
I don't want to use an omit style approach.
const filtered = arr.filter(obj => obj.hasOwnProperty("a") || obj.hasOwnProperty("fred"));
// or, if you have dynamic / lots of keys:
const keys = ["a", "fred"];
const filtered = arr.filter(obj => keys.some(key => obj.hasOwnProperty(key));
filter method will be useful. Create a function and pass an array of keys. Inside filter function check if the key is matching with the parameter array. If it passed then return that object
var orgObject = [{
a: 2
}, {
b: 3
}, {
fred: 10
}];
function searchByKey(keyNames) {
return orgObject.filter(function(item) {
for (var keys in item) {
if (keyNames.indexOf(keys) !== -1) {
return item
}
}
})
}
console.log(searchByKey(['a', 'fred']))
Basically you want all the objects from the array who have the fields a or fred. You can use the hasOwnProperty() on the objects while filtering.
_.filter(array, elem => elem.hasOwnProperty('a') || elem.hasOwnProperty('fred'));

Javascript create array of objects dynamically

I have a JSON response i.e.
[{"name":"title","value":"STEP-01","translation":"STEP-01"},{"name":"meta_description","value":"","translation":"meta desc"}, ......]
from this I want to create an array of objects dynamically so that I get name as key and translation as value
like
data.en = {
title : 'STEP-01',
meta-description : meta desc
}
I have tried this but it creates an array
jsonObj = []
$.each(result, function (index, value) {
lang_array = {};
lang_array[value.name] = value.translation;
jsonObj.push(lang_array);
})
According to your example you are trying to create a JS object, and not an array.
Option 1: Use Array#reduce to collect the name and translation of each object to a new object:
const data = [{"name":"title","value":"STEP-01","translation":"STEP-01"},{"name":"meta_description","value":"","translation":"meta desc"}];
const result = data.reduce((r, { name, translation }) => {
r[name] = translation;
return r;
}, {});
console.log(result);
Option 2: Use a Array#map to create a collection of objects with the properties and the values, and combine them to a single object using Object#assign and spread:
const data = [{"name":"title","value":"STEP-01","translation":"STEP-01"},{"name":"meta_description","value":"","translation":"meta desc"}];
const result = Object.assign(...data.map(({ name, translation }) => ({ [name]: translation })));
console.log(result);

Categories

Resources