I've got some headers and peopleData:
const headers = ["name", "age", "nationality"]
const peopleData = [
["John", 31, "Spanish"],
["Jane", 41, "Italian"],
["Johnson", 11, "Thai"],
["Rob", 13, "Japanese"],
]
I want to combine both and return an array of objects looking like:
[{
name: "John",
age: 31,
nationality: "Spanish"
}, {
name: "Jane",
age: 41,
nationality: "Italian"
}, {
name: "Johnson",
age: 11,
nationalityL: "Thai"
}, {
name: "Rob",
age: 13,
nationality: "Japanese"
}]
So far I came up to this:
const people = peopleData.map((person, i) => {
return headers.map((header, index) => {
return {
[header]: person[index]
}
})
})
This solution does not work since it creates nested objects:
[[{
name: "John"
}, {
age: 31
}, {
nationality: "Spanish"
}], [{
name: "Jane"
}, {
age: 41
}, {
nationality: "Italian"
}], [{
name: "Johnson"
}, {
age: 11
}, {
nationality: "Thai"
}], [{
name: "Rob"
}, {
age: 13
}, {
nationality: "Japanese"
}]]
Example below:
Credit to Andreas comment, better performant below
const headers = ["name", "age", "nationality"];
const peopleData = [
["John", 31, "Spanish"],
["Jane", 41, "Italian"],
["Johnson", 11, "Thai"],
["Rob", 13, "Japanese"],
];
const o = peopleData.map(a =>
a.reduce((acc, b, i) => {
acc[headers[i]] = b;
return acc;
}, {})
);
console.log(o);
In one line-er, but less performent
const headers = ["name", "age", "nationality"];
const peopleData = [
["John", 31, "Spanish"],
["Jane", 41, "Italian"],
["Johnson", 11, "Thai"],
["Rob", 13, "Japanese"],
];
const o = peopleData.map(a =>
a.reduce((acc, b, i) => ({ ...acc, [headers[i]]: b }), {})
);
console.log(o);
You can wrap your inner .map() in a call to Object.fromEntries() which will build an object for you - it takes an array of [[key, value],...] pairs, and so you can change your inner map to return a [key, value] pair array instead of objects like so:
const headers = ["name", "age", "nationality"];
const peopleData = [ ["John", 31, "Spanish"], ["Jane", 41, "Italian"], ["Johnson", 11, "Thai"], ["Rob", 13, "Japanese"], ];
const res = peopleData.map(person => Object.fromEntries(person.map(
(val, i) => [headers[i], val]
)));
console.log(res);
Or, you can stick with your approach of returning an array of objects, but then merge the objects within the array together using Object.assign() and the spread syntax ...:
const headers = ["name", "age", "nationality"];
const peopleData = [ ["John", 31, "Spanish"], ["Jane", 41, "Italian"], ["Johnson", 11, "Thai"], ["Rob", 13, "Japanese"], ];
const res = peopleData.map(person => Object.assign(...person.map(
(val, i) => ({[headers[i]]: val})
)));
console.log(res);
A simply solution easy to understand! Iterate all peopleData and put them in a new object using the array headers:
const headers = ["name", "age", "nationality"];
const peopleData = [["John", 31, "Spanish"],["Jane", 41, "Italian"],["Johnson", 11, "Thai"],["Rob", 13, "Japanese"]];
let result = [];
peopleData.forEach((e, i) => { //iterate data
result[i] = {};
result[i][headers[0]] = e[0];
result[i][headers[1]] = e[1];
result[i][headers[2]] = e[2];
});
console.log(result);
Related
I need to filter an array of objects
const arrayOne = [
{id: 33, name: "fruit"},
{id: 157, name: "car"},
{id: 193, name: "water"},
];
const arrayTwo = [33, 193];
I need only the names in an array (without the key)
Expected output
["fruit", "water"]
1) You can easily achive the result using Map
const arrayOne = [
{ id: 33, name: "fruit" },
{ id: 157, name: "car" },
{ id: 193, name: "water" },
];
const map = new Map();
arrayOne.forEach((o) => map.set(o.id, o.name));
const arrayTwo = [33, 193];
const result = arrayTwo.map((o) => map.get(o));
console.log(result);
2) You can also achieve the result using map and find
const arrayOne = [
{ id: 33, name: "fruit" },
{ id: 157, name: "car" },
{ id: 193, name: "water" },
];
const arrayTwo = [33, 193];
const result = arrayTwo.map((id) => arrayOne.find((o) => o.id === id)?.name);
console.log(result);
you can just simply do
const arrayOne = [
{ id: 33, name: "fruit" },
{ id: 157, name: "car" },
{ id: 193, name: "water" }
];
const arrayTwo = [33, 193];
let keepResult = [];
arrayOne.map((a1) => {
arrayTwo.map((a2) => {
if (a1.id === a2) {
keepResult.push(a1.name);
}
});
});
console.log("result show", keepResult);
const arrayOne = [
{id: 33, name: "fruit"},
{id: 157, name: "car"},
{id: 193, name: "water"},
];
const arrayTwo = [33, 193];
let newArray = arrayOne.filter(item => arrayTwo.includes(item.id)).map(item => item.name)
console.log(newArray);
try this
this function is your solution:
const findNames = () => {
let names = []
arrayOne.forEach(item => {
if (arrayTwo.includes(item.id)) {
names = [...names, item.name]
}
})
return names
}
Here is your compare() function for getting array of names based on two array
const arrayOne = [
{id: 33, name: "fruit"},
{id: 157, name: "car"},
{id: 193, name: "water"},
];
const arrayTwo = [33, 157];
function compare(arrayOne, arrayTwo) {
let result = [];
arrayOne.filter(element => arrayTwo.indexOf(element.id) !== -1 ).forEach(element => { result.push(element.name) });
return result ;
}
Use a flatmap on the first array and include only those members having an id property included in array two.
arrayOne.flatMap(({ id, name }) => arrayTwo.includes(id) ? [name]: []);
const arrayOne = [
{id: 33, name: "fruit"},
{id: 157, name: "car"},
{id: 193, name: "water"},
];
const arrayTwo = [33, 193];
const result = arrayOne.flatMap(({ id, name }) => arrayTwo.includes(id) ? [name]: []);
console.log(result);
I have added Computer Marks Manually But I have to add ComputerMarks Field through looping to use the given JSON Array which is AnotherSubject To Match The Student Name with JASON Array then Add ComputerMarks field to each student JASON File
let Student1={
Name:"Mark",
MathMarks:80,
EnglishMarks:75,
ScienceMarks:63,
}
let Student2={
Name:"Bob",
MathMarks:90,
EnglishMarks:81,
ScienceMarks:88,
}
let Student3={
Name:"Julia",
MathMarks:88,
EnglishMarks:87,
ScienceMarks:89,
}
let Student4={
Name:"Anthony",
MathMarks:60,
EnglishMarks:64,
ScienceMarks:61,
}
let AnotherSubject=[
{name:'Mark', ComputersMarks:90},
{name:'Anthony', ComputersMarks:70},
{name:'Julia', ComputersMarks:88},
{name:'Bob', ComputersMarks:81}]
StudentsArray=[Student1,Student2,Student3,Student4]
let StudentMarks={
students:StudentsArray
}
Student1.ComputersMarks=90
Student2.ComputersMarks=81
Student3.ComputersMarks=88
Student4.ComputersMarks=70
console.log(StudentMarks.students)
a possible way
const
Student1 = { Name: 'Mark', MathMarks: 80, EnglishMarks: 75, ScienceMarks: 63 }
, Student2 = { Name: 'Bob', MathMarks: 90, EnglishMarks: 81, ScienceMarks: 88 }
, Student3 = { Name: 'Julia', MathMarks: 88, EnglishMarks: 87, ScienceMarks: 89 }
, Student4 = { Name: 'Anthony', MathMarks: 60, EnglishMarks: 64, ScienceMarks: 61 }
, StudentsList = [ Student1, Student2, Student3, Student4 ]
, AnotherSubject =
[ { Name: 'Mark', ComputersMarks: 90 }
, { Name: 'Anthony', ComputersMarks: 70 }
, { Name: 'Julia', ComputersMarks: 88 }
, { Name: 'Bob', ComputersMarks: 81 }
]
function addNewProp ( List, newRefs )
{
let [key,prop] = Object.keys( newRefs[0])
List.forEach(el =>
{
let newP = newRefs.find(x=>x[key]===el[key] )
if (newP) el[prop] = newP[prop]
});
}
addNewProp(StudentsList, AnotherSubject)
console.log('Student1 ->', JSON.stringify( Student1) )
console.log('Student2 ->', JSON.stringify( Student2) )
console.log('Student3 ->', JSON.stringify( Student3) )
console.log('Student4 ->', JSON.stringify( Student4) )
.as-console-wrapper {max-height: 100%!important;top:0}
One easy way to do this would be to use the power of reduce and map.
Reduce basically makes an Object from an Array and Map transforms each item of an array and return the new array.
Additionally, we use the spear syntax ... to manipulate objects.
// Here we are converting [{name: '', marks: 1 }] into { name: marks }
const AnotherSubjectsMap = AnotherSubject.reduce((accu, curr) => ({
...accu,
[curr.name]: curr.ComputersMarks
}), {});
let StudentsArray = [Student1, Student2, Student3, Student4]
// Here were are going through the array and adding an extra parameter
StudentsArray = StudentsArray.map(Student => ({
...Student, // This line means we are copying all keys of Student as it is
ComputersMarks: AnotherSubjectsMap[Student.Name]
}));
let StudentMarks = {
students: StudentsArray
}
console.log(StudentMarks.students)
let Student1 = {
Name: "Mark",
MathMarks: 80,
EnglishMarks: 75,
ScienceMarks: 63,
}
let Student2 = {
Name: "Bob",
MathMarks: 90,
EnglishMarks: 81,
ScienceMarks: 88,
}
let Student3 = {
Name: "Julia",
MathMarks: 88,
EnglishMarks: 87,
ScienceMarks: 89,
}
let Student4 = {
Name: "Anthony",
MathMarks: 60,
EnglishMarks: 64,
ScienceMarks: 61,
}
let AnotherSubject = [{
name: 'Mark',
ComputersMarks: 90
},
{
name: 'Anthony',
ComputersMarks: 70
},
{
name: 'Julia',
ComputersMarks: 88
},
{
name: 'Bob',
ComputersMarks: 81
}
]
AnotherSubjectsMap = AnotherSubject.reduce((accu, curr) => ({
...accu,
[curr.name]: curr.ComputersMarks
}), {});
StudentsArray = [Student1, Student2, Student3, Student4]
StudentsArray = StudentsArray.map(Student => ({
...Student,
ComputersMarks: AnotherSubjectsMap[Student.Name]
}));
let StudentMarks = {
students: StudentsArray
}
console.log(StudentMarks.students)
I have an array of objects of the structure coming from server response of iterated array object like as sample
var arrObj1 = [
{"id":"1","value":21, "value1":13},
{"id":"2","value":21, "value1":13 },
......n
];
var arrObj2 = [
{"id":"1","value3":21, "value14":13},
{"id":"2","value3":21, "value4":13 },
......n
];
var arrObj3 = [
{"id":"1","value5":21, "value6":13},
{"id":"2","value5":21, "value6":13 },
......n
];
But now I want to append the array values inot single new array according to key following structure of as iterated values of above array Expected Output:
var finalObj = [
{
"id" : 1
"value" : 21,
"value1" : 13,
"value3" : 21,
"value4" : 13,
"value5" : 21,
"value6" : 13,
},
{
"id" : 2
"value" : 21,
"value1" : 13,
"value3" : 21,
"value4" : 13,
"value5" : 21,
"value6" : 13,
},
.....n
];
You can use reduce for concated arrays
const arrObj1 = [
{ id: '1', value: 21, value1: 13 },
{ id: '2', value: 21, value1: 13 },
];
const arrObj2 = [
{ id: '1', value3: 21, value14: 13 },
{ id: '2', value3: 21, value4: 13 },
];
const arrObj3 = [
{ id: '1', value5: 21, value6: 13 },
{ id: '2', value5: 21, value6: 13 },
];
const result = [...arrObj1, ...arrObj2, ...arrObj3].reduce(
(acc, { id, ...rest }) => ({ ...acc, [id]: acc[id] ? { ...acc[id], ...rest } : { ...rest } }),
{},
);
console.log(Object.entries(result).map(([id, data]) => ({ id, ...data })));
Push you arrays to a new array (you have to have your sub arrays in other list to loop through them) and then use flat, after that group your object according to the id property
var arrObj1 = [{
"id": "1",
"value": 21,
"value1": 13
},
{
"id": "2",
"value": 21,
"value1": 13
},
];
var arrObj2 = [{
"id": "1",
"value3": 21,
"value14": 13
},
{
"id": "2",
"value3": 21,
"value4": 13
},
];
var arrObj3 = [{
"id": "1",
"value5": 21,
"value6": 13
},
{
"id": "2",
"value5": 21,
"value6": 13
},
];
const input = [];
input.push(arrObj2, arrObj3);
const preResult = input.flat();
result = preResult.reduce((acc, x) => {
const index = acc.findIndex(y => y.id === x.id)
if (index >= 0) {
acc[index] = {
...acc[index],
...x
}
} else {
acc.push(x)
}
return acc;
}, arrObj1)
console.log(result)
You can iterate over array-length and push here for every entry 1 entry to the result. For getting this entry take a new object with the id and iterate over all (3 or perhaps more) arrays. For every array take the i-th entry and push for every key an entry with key:value (except for the key id itself).
Remark: You can use as much arrays you want and every object could contain as much value-prperties as you need. The only restriction is that every array has the same count of objects.
var arrObj1 = [
{"id":"1","value":21, "value1":13},
{"id":"2","value":21, "value1":13 }
];
var arrObj2 = [
{"id":"1","value3":21, "value4":13},
{"id":"2","value3":21, "value4":13 }
];
var arrObj3 = [
{"id":"1","value5":21, "value6":13},
{"id":"2","value5":21, "value6":13 }
];
let result =[];
let arrayAll = [arrObj1, arrObj2, arrObj3];
for (let i=0; i<arrayAll[0].length; i++) {
let obj = arrayAll[0][i];
let res = { id: obj.id};
for (let j=0; j<arrayAll.length; j++) {
let obj = arrayAll[j][i];
Object.keys(obj).forEach(key => {
if (key!='id') res[key] = obj[key];
})
}
result.push(res);
}
console.log(result);
Since you are using id to merge multiple objects, Map is one of the good option to merge.
let arrObj1 = [
{"id":"1","value":21, "value1":13},
{"id":"2","value":21, "value1":13 },
];
let arrObj2 = [
{"id":"1","value3":21, "value14":13},
{"id":"2","value3":21, "value4":13 },
];
let arrObj3 = [
{"id":"1","value5":21, "value6":13},
{"id":"2","value5":21, "value6":13 },
];
let mergedArray = [...arrObj1,...arrObj2,...arrObj3].reduce((acc,curr) =>{
if(acc.has(curr.id)){
acc.set(curr.id, {...acc.get(curr.id),...curr});
}else{
acc.set(curr.id,curr);
}
return acc;
},new Map())
console.log(Array.from(mergedArray,x=>x[1]));
I am new to javascript. lets say I have the following object of arrays
const object1 = {
name: ['David', 'Juan', 'Simon', 'Lukas'],
age: [41, 22, 33, 50],
salary: [100, 80, 120, 150]
};
I would like to create a new object which filter the data of people older than a value (e.g. 30). I was loooking to filter, Object.fromEntries, Object.entries but I couldnt find a possible solution.
The result should be
NewObject {
name: Array['David', 'Simon', 'Lukas'],
age: Array[41, 33, 50],
salary: Array[100, 120, 150]
};
Thanks for any suggestions
Convert your current structure to a more convenient data structure(JSON) like this:
const workers = [
{
name : 'David',
age : 41,
salary : 100
},
{
name : 'Juan',
age : 22,
salary : 80
},
{
name : 'Simon',
age : 33,
salary : 120
},
{
name : 'Lukas',
age : 50,
salary : 150
}
];
const olderThan30 = workers.filter(worker => worker.age > 30);
console.log(olderThan30);
// This console log will return this, an array of JSON objects that match the criteria of the filter function.
// [
// { name : "David", age : 41, salary : 100 },
// { name : "Simon", age : 33, salary : 120 },
// { name : "Lukas", age : 50, salary : 150 }
// ]
I hope this will help.
Like #CharlieFish mentioned, your data structure is not the normal way of doing things, which is where you'd do this instead:
const employees = [
{ name: 'David', age: 41, salary: 100 },
{ name: 'Simon', age: 33, salary: 120 },
{ name: 'Lukas', age: 50, salary: 150 },
];
const over30 = employees.filter(employee => employee.age > 30);
If you did need to stick with your pattern instead, you can still do it, but you'd have to filter each individual array:
const isOver30 = (_, i) => object1.age[i] > 30;
const thoseOver30 = {
name: object1.name.filter(isOver30),
age: object1.age.filter(isOver30),
salary: object1.salary.filter(isOver30)
}
...or less duplicative:
const thoseOver30 = Object
.entries(object1)
.map(([prop, array]) => ({ [prop]: array.filter(isOver30) }))
.reduce((result, props) => Object.assign(result, props), {});
An easy to understand solution:
const maxAge = 30;
const object = {
name: ['David', 'Juan', 'Simon', 'Lukas'],
age: [41, 22, 33, 50],
salary: [100, 80, 120, 150]
};
const result = { name: [], age: [], salary: [] };
for (let i = 0; i < object.name.length; i++) {
if (object.age[i] <= maxAge) {
result.name = [...result.name, object.name[i]];
result.age = [...result.age, object.age[i]];
result.salary = [...result.salary, object.salary[i]];
}
}
console.log(result);
You could create one object where keys are indexes of the elements where age >= 30 and then use that object as hash table for filtering.
const data = {
name: ['David', 'Juan', 'Simon', 'Lukas'],
age: [41, 22, 33, 50],
salary: [100, 80, 120, 150]
}
const hash = data.age.reduce((r, e, i) => {
if (e >= 30) r[i] = true;
return r;
}, {})
for (let i in data) {
data[i] = data[i].filter((_, j) => hash[j])
}
console.log(data)
You could also use different data structure to get an array of objects with reduce method and then just apply filter.
const data = {
name: ['David', 'Juan', 'Simon', 'Lukas'],
age: [41, 22, 33, 50],
salary: [100, 80, 120, 150]
}
const result = Object
.entries(data)
.reduce((r, [k, v]) => {
v.forEach((e, i) => {
if (!r[i]) r[i] = {}
r[i][k] = e;
})
return r;
}, [])
.filter(({ age }) => age >= 30)
console.log(result)
With this array:
var booksStudents = [
{
name: "David",
books: {
"fantasy": 23,
"action": 31,
"thriller" 21,
}
},
name: "Paul",
books: {
"fantasy": 17,
"action": 13,
"thriller" 23,
}
},
name: "Zoe",
books: {
"fantasy": 5,
"action": 7,
"thriller" 28,
}
}];
I would like to return an array of objects, each containing the name of a person and the sum of all their respective books.
I know how to use the reduce method on a simple array but I am stuck with this array of object.
I was thinking of using .map and .reduce but I did not find something interesting.
booksStudents = booksStudents.map(function(item){
var count = 0;
for(var key in item.books){
count+=item.books[key];
}
item.count = count;
return item;
})
use map and for..in to count the number.
Firstly there are few mistakes in your array of objects, Let me point them.
var booksStudents = [
{
name: "David",
books: {
"fantasy": 23,
"action": 31,
"thriller": 21, // : missing
}
},
{ // { missing
name: "Paul",
books: {
"fantasy": 17,
"action": 13,
"thriller": 23, // : missing
}
},
{ // { missing
name: "Zoe",
books: {
"fantasy": 5,
"action": 7,
"thriller": 28, // : missing
}
}];
So now after this is fixed the solution to get your end result is by using this code.
var newArray = [];
$.each(booksStudents,function(index,value){
var currObj = {};
currObj.name= this.name;
currObj.totalBooks = parseInt(this.books.fantasy) +parseInt(this.books.action)+parseInt(this.books.thriller) ;
newArray.push(currObj);
});
console.log(newArray);
Here is a Wroking Fiddle check console for output
The output is as below .