Related
Input :
// First Array
const input1 = [{
'name': "name1",
'email': "email1#email.com",
'age': 10,
'score':95,
'address': {
'city': "city1"
}
},
{
'name': "name2",
'email': "email2#email.com",
'age': 10,
'score':45,
'address': {
'city': "city2"
}
}
];
// Second Array
const input2 = [{
'id': 1,
'fullname': "name1",
'emailaddress': "email1#email.com",
'age': 10,
'score':45,
'address': {
'city': "city1"
}
},
{
'id': 5,
'name': "name2",
'email': "email2#email.com",
'age': 20,
'score':55,
'address': {
'city': "city2"
}
}
];
const filter1 = [{
"filter1Key": "age",
"filter2Key": "score"
}];
const filter2 = [{
"filter1Key": "name",
"filter2Key": "address.city"
}];
const newArray = [];
cont updateArray = [];
//Below code is not is giving
const test1 = input1.filter((data) => input2.some((obj) =>
filter1.every(key => data[key.filter1Key] === obj[key.filter2Key])?filter2.every(key => data[key.filter1Key] === obj[key.filter2Key])?'':updateArray.push(obj):newArray.push(obj)));
console.log(test1);
First all the unmatched record with filter1 of input1 should be push into newArray and unmatched record with filter2 of input1 should be push into updateArray but id of inout2 should also push with that record
Expected output:
newArray = [{
'name': "name1",
'email': "email1#email.com",
'age': 10,
'score':95,
'address': {
'city': "city1"
}
}];
updateArray = [{
'id': 5,
'name': "name2",
'email': "email2#email.com",
'age': 10,
'score':45,
'address': {
'city': "city2"
}
}]
Convert the first ? to && and the second ? to == and the first : to ?
you may change below code by your es6+ syntax--
I wish It might help you
input1.forEach((input1Item) => {
const x = input2.find((input2Item) =>{
return input1Item[filter1[0].filter1Key] === input2Item[filter1[0].filter1Key] && input1Item[filter1[0].filter2Key] === input2Item[filter1[0].filter2Key]
})
const y = input2.find((input2Item) =>{
return input1Item[filter1[0].filter1Key] !== input2Item[filter1[0].filter1Key] || input1Item[filter1[0].filter2Key] !== input2Item[filter1[0].filter2Key]
})
if(!x){
newArray.push(input1Item)
} else if(y){
updateArray.push({ id: y.id , ...input1Item})
}
});
I have an array with correct order line:
let arr1 = ['name', 'age', 'occupation', 'address']
and I have an another array which is coming from the backend with unsorted format
let arr2 = [{'age': 20, 'address': '', 'occupation': 'student', 'name': 'student name1'}, {'age': 21, 'address': '', 'occupation': 'student', 'name': 'student name2'}, {'age': 22, 'address': '', 'occupation': 'student', 'name': 'student name3'}]
So I need this arr2 objects keys to be sorted the way arr1 keys index positions.
Final output needed:
let arr2Sorted = [{ 'name': 'student name1', 'age': 20, 'occupation': 'student', 'address': ''}, { 'name': 'student name2', 'age': 21, 'occupation': 'student', 'address': ''}, { 'name': 'student name3', 'age': 22, 'occupation': 'student', 'address': ''}]
What I tried:
const arrayMap = arr2.reduce(
(accumulator, currentValue) => ({
...accumulator,
[currentValue]: currentValue,
}),
{},
);
const result = arr1.map((key) => arrayMap[key]);
let arr1 = ['name', 'age', 'occupation', 'address'];
let arr2 = [{'age': 20, 'address': '', 'occupation': 'student', 'name': 'student name1'}, {'age': 21, 'address': '', 'occupation': 'student', 'name': 'student name2'}, {'age': 22, 'address': '', 'occupation': 'student', 'name': 'student name3'}];
let arr3 = arr2.map(i=>Object.fromEntries(arr1.map(p=>[p,i[p]])));
console.log(arr3);
Here I show why it is probably not needed to order the properties, but just use them. I also answer the "How To" in a verbose way.
let arr1 = ['name', 'age', 'occupation', 'address'];
let arr2 = [{
'age': 20,
'address': '',
'occupation': 'student',
'name': 'student name1'
}, {
'age': 21,
'address': '',
'occupation': 'student',
'name': 'student name2'
}, {
'age': 22,
'address': '',
'occupation': 'student',
'name': 'student name3'
}];
// show it is not needed to order props, just use them
const container = document.getElementById("container");
arr2.forEach((el) => {
arr1.forEach((nm) => {
const newtext = document.createTextNode(nm + ":" + el[nm]);
let dv = document.createElement('div');
dv.appendChild(newtext);
container.appendChild(dv);
});
});
// now show how we an order the props - a number of ways to do this
// this is a super verbose way for clarity
let arrPropsOrdered = [];
arr2.forEach((el, index, array) => {
// console.log("PropName:",arr1[0]);
// console.log("Object:",el);
// console.log("ObjectNameProp:",el[arr1[0]]);
let x = {};
/* manual way
x[arr1[0]] = el[arr1[0]];
x[arr1[1]] = el[arr1[1]];
x[arr1[2]] = el[arr1[2]];
x[arr1[3]] = el[arr1[3]];
*/
// in a loop
arr1.forEach((nm) => {
x[nm] = el[nm];
});
// console.log("X:", x);
arrPropsOrdered.push(x);
// show it pushed in there using the current index
// console.log("PropsByPropName:", arrPropsOrdered[index]);
});
// console.log(arrPropsOrdered);
<div id="container"></div>
Lets say I am having the following list which is called indexesToBeRemoved:
indexesTobeRemoved = ['auto_id', 'auto_date']
I want to loop over the following array of arrays:
allArrays = [
{
'auto_id': 123,
'auto_date': '2019-02-02',
'name': 'John Doe',
'address': 'USA'
},
{
'auto_id': 147,
'auto_date': '2019-03-02',
'name': 'Peter Doe',
'address': 'USA'
},
{
'auto_id': 258,
'auto_date': '2019-04-02',
'name': 'Hanna Doe',
'address': 'USA'
}
];
I need to loop over each array within this array to remove fields that exists in the list indexesTobeRemoved. Therefore, the array of arrays would look like the following:
allArrays = [
{
'name': 'John Doe',
'address': 'USA'
},
{
'name': 'Peter Doe',
'address': 'USA'
},
{
'name': 'Hanna Doe',
'address': 'USA'
}
];
I tried the following:
removeIndexes() {
this.indexesTobeRemoved.forEach((value) => {
console.log(value);
Object.keys(this.allArrays).forEach((key, val) => {
this.allArrays.splice(value, 1);
console.log(this.allArrays[key]);
});
})
But on execution, the array allArray will become empty.
Here is a stackblitz.
You can use nested forEach() loop and delete operator
const allArrays = [ { 'auto_id': 123, 'auto_date': '2019-02-02', 'name': 'John Doe', 'address': 'USA' }, { 'auto_id': 147, 'auto_date': '2019-03-02', 'name': 'Peter Doe', 'address': 'USA' }, { 'auto_id': 258, 'auto_date': '2019-04-02', 'name': 'Hanna Doe', 'address': 'USA' } ];
let keys = ['auto_id', 'auto_date'];
allArrays.forEach(x => {
keys.forEach(k => delete x[k])
})
console.log(allArrays)
Instead of forEach please use map.
Here's an explanation why:
https://gofore.com/en/why-you-should-replace-foreach/
What you were searching for was the delete operator. The JavaScript delete operator removes a property from an object; if no more references to the same property are held, it is eventually released automatically.
this.indexesTobeRemoved.map(key => {
this.allArrays.map(array => delete array[key]);
});
how can i convert 1 array or separate its values to multiple array in javascript?
i got an array like this:
const data =
[
{
'Name': 'John'
'Age': 20
'Company': 'Google'
},
{
'Name': 'Philip'
'Age': 21
'Company': 'Mozzila'
},
{
'Name': 'Matthew'
'Age': 22
'Company': 'Microsoft'
},
{
'Name': 'Peter'
'Age': 23
'Company': 'Accenture'
},
]
how can i transform that array like this:
data = {
'Data1':['John', 'Philip','Matthew', 'Peter'],
'Data2':[20,21,22,23]
'Data3':['Google','Mozzila','Microsoft','Accenture']
}
or like this:
data = {
'Name':['John', 'Philip','Matthew', 'Peter'],
'Age':[20,21,22,23]
'Company':['Google','Mozzila','Microsoft','Accenture']
}
Here's an answer using reduce:
const data = [
{
'Name': 'John',
'Age': 20,
'Company': 'Google'
},
{
'Name': 'Philip',
'Age': 21,
'Company': 'Mozzila'
},
{
'Name': 'Matthew',
'Age': 22,
'Company': 'Microsoft'
},
{
'Name': 'Peter',
'Age': 23,
'Company': 'Accenture'
},
];
const results = data.reduce((a, e) => {
for (const key in e) {
if (!(key in a)) {
a[key] = [];
}
a[key].push(e[key]);
}
return a;
}, {});
console.log(results);
The idea is for each object in data, loop over its keys and push each value into an array in the destination object. This might be a little slow, but it works regardless of the names of your keys and is reasonably terse.
Below uses reduce to iterate over the data array and build an object as it does. This is done dynamically by iterating over each object's keys.
The consistency of your objects are essential. If one object has more keys than another, the array indexes will no longer be kept in sync.
const data = getData();
const obj = data.reduce((obj, curr) => {
Object.keys(curr).forEach(key => {
if (!Array.isArray(obj[key]))
obj[key] = []
obj[key].push(curr[key])
})
return obj
}, {})
console.log(obj);
// Data:
function getData() {
return [{
'Name': 'John',
'Age': 20,
'Company': 'Google'
},
{
'Name': 'Philip',
'Age': 21,
'Company': 'Mozzila'
},
{
'Name': 'Matthew',
'Age': 22,
'Company': 'Microsoft'
},
{
'Name': 'Peter',
'Age': 23,
'Company': 'Accenture'
}
]
}
Alternative
An alternative is to describe which key to keep. Notice I've removed some of your key/value pairs from the data structure. See how the resulting object is kept in sync by inserting an undefined in the value's place:
const data = getData(),
keys = ['Name', 'Age', 'Company'];
const obj = data.reduce((result, item) => {
keys.forEach(key => {
if (!Array.isArray(result[key]))
result[key] = []
result[key].push(item[key])
})
return result
}, {})
console.log(obj);
// Data:
function getData() {
return [{
'Age': 20,
'Company': 'Google'
},
{
'Name': 'Philip',
'Age': 21
},
{
'Name': 'Matthew',
'Company': 'Microsoft'
},
{
'Name': 'Peter',
'Age': 23,
'Company': 'Accenture'
}
]
}
Another approach ,You can have seperate map for each keys . keeping it simple
const data =
[
{
'Name': 'John',
'Age': 20,
'Company': 'Google'
},
{
'Name':'Philip',
'Age': 21,
'Company': 'Mozzila'
},
{
'Name':'Matthew',
'Age': 22,
'Company': 'Microsoft'
},
{
'Name': 'Peter',
'Age': 23,
'Company': 'Accenture'
},
];
let a={'Name':data.map(d=>d.Name),'Age':data.map(d=>d.Age),'Company':data.map(d=>d.Company)};
console.log(a);
var data = [
{
"name" : "xxx",
"age" : 20,
"company" : "aaa"
},
{
"name" : "yyy",
"age" : 30,
"company" : "bbb"
},
{
"name" : "zzz",
"age" : 40,
"company" : "ccc"
}
];
var newData = {};
for(var x =0 ; x < data.length; x++){
for(var obj in data[x]){
if(!newData[obj]){
newData[obj] = [];
}
newData[obj].push( data[x][obj] );
}
}
console.log(newData);
/* Result */
/*
{
name: ["xxx", "yyy", "zzz"],
age: [20, 30, 40],
company: ["aaa", "bbb", "ccc"]
}
*/
Please,
I have this JSON object and want to group values by type.
var costs = [
{ 'name': 'JON', 'flight':100, 'value': 12, type: 'uns' },
{ 'name': 'JON', 'flight':100, 'value': 35, type: 'sch' },
{ 'name': 'BILL', 'flight':200, 'value': 33, type: 'uns' },
{ 'name': 'BILL', 'flight':200, 'value': 45, type: 'sch' }
];
I want something like this:
var costs = [
{ 'name': 'JON', 'flight':100, 'uns': 12, 'sch': 35 },
{ 'name': 'BILL', 'flight':200, 'uns': 33, 'sch': 45}
];
I try use lodash but without sucess:
var compiled_costs = _.chain(costs)
.groupBy("flight")
.value();
{
"100":
[ {"name":"JON","flight":100,"value":12,"type":"uns"},
{"name":"JON","flight":100,"value":35,"type":"sch"}
],
"200":
[
{"name":"BILL","flight":200,"value":33,"type":"uns"},
{"name":"BILL","flight":200,"value":45,"type":"sch"}
]
}
var res = _.chain(costs)
.groupBy('flight') // group costs by flight
.mapValues(function(flightItems, flight) { // iterate flight arrays
return { // return obj on each flight array
name: _.get(flightItems, [0, 'name']), // just get name from first item of flight array
flight: flight,
uns: _.chain(flightItems) // get all flight items with type uns and sum items values
.filter({type: 'uns'})
.sumBy('value')
.value(),
sch: _.chain(flightItems)
.filter({type: 'sch'})
.sumBy('value')
.value()
}
})
.values() // get values from object
.value();
You can use native reduce() method:
const costs = [
{ 'name': 'JON', 'flight':100, 'value': 12, type: 'uns' },
{ 'name': 'JON', 'flight':100, 'value': 35, type: 'sch' },
{ 'name': 'BILL', 'flight':200, 'value': 33, type: 'uns' },
{ 'name': 'BILL', 'flight':200, 'value': 45, type: 'sch' }
];
const compiledCosts = costs.reduce((acc, { name, flight, value, type }) => {
let obj = acc.find(x => x.name === name);
if (typeof obj === 'undefined') {
acc.push({ name, flight, [type]: value });
} else {
obj[type] = value;
}
return acc;
}, []);
console.log(compiledCosts);
You could use a closure over a hash table for same named objects.
var data = [{ name: 'JON', flight: 100, value: 12, type: 'uns' }, { name: 'JON', flight: 100, value: 35, type: 'sch' }, { name: 'BILL', flight: 200, value: 33, type: 'uns' }, { name: 'BILL', flight: 200, value: 45, type: 'sch' }],
grouped = data.reduce(function (hash) {
return function (r, o) {
if (!hash[o.name]) {
hash[o.name] = { name: o.name, flight: o.flight };
r.push(hash[o.name]);
}
hash[o.name][o.type] = (hash[o.name][o.type] || 0) + o.value;
return r;
}
}(Object.create(null)), []);
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
This is what Map was made for. Since you are merging the data you might want to consider keeping the hashMap for quicker lookup. Otherwise turning it into an array is trivial as I demonstrate.
function compiled_costs(costs) {
var hash = new Map();
for (let cost of costs) {
if (hash.has(cost.name)) {
var values = hash.get(cost.name),
value = values.value,
type = values.type;
delete values.value;
delete values.type;
values.uns = value;
values.sch = cost.value;
} else hash.set(cost.name, cost)
}
return hash
}
var costs = [{
'name': 'JON',
'flight': 100,
'value': 12,
type: 'uns'
},
{
'name': 'JON',
'flight': 100,
'value': 35,
type: 'sch'
},
{
'name': 'BILL',
'flight': 200,
'value': 33,
type: 'uns'
},
{
'name': 'BILL',
'flight': 200,
'value': 45,
type: 'sch'
}
];
var formated = [...compiled_costs(costs).values()];
//formated
console.log('formated',formated);
//hashed
var hashed = [...compiled_costs(costs)];
console.log('hashed',hashed);