How to push an array with objects into an array - javascript

I am a newbie here so my question may sound stupid.
I have an array with multiple objects and I am not sure how to push the key name of each object to an array.
This is my code:
var ingredients = [
{ id: 1, name: "onion", mineralsUnit: "mg", water: 89.11 },
{ id: 2, name: "carrot", calcium: 23, iron: 0.21, otherUnit: "g", water: 89.11 },
{ id: 3, name: "peanut", iron: 0.21, otherUnit: "g", water: 89.11 }
];
and I've created a new empty array where I want to add just the name from the first array
var myIngredients = [];
I've tried that:
for (var i = 0; i < ingredients.length; i++) {
myIngredients.push(ingredients[i]);
}
but it returns the entire array and even though I select in here ingredients[I] what element I want to pick it's still not working.
If someone has an idea I would really appreciate it. Thanks a lot.

with es6 you can use map
try myIngredients = ingredients.map(ingredient => ingredients.name)

You were very close. This will push the name value of every object in the ingredients array
for (var i = 0; i < ingredients.length; i++) {
myIngredients.push(ingredients[i].name);
}

Just don't forget the comma after peanut!
var myIngredients = [];
ingredients.forEach(
ingredient =>
myIngredients.push(ingredient.name)
)
console.log(myIngredients)

You can use the map function:
var ingredients = [
{ id: 1, name: "onion", mineralsUnit: "mg", water: 89.11},
{ id: 2, name: "carrot", calcium: 23, iron: 0.21, otherUnit: "g", water: 89.11 },
{ id: 3, name: "peanut", iron: 0.21, otherUnit: "g", water: 89.11, }
];
var myIngredients = ingredients.map(e => e.name);
console.log(myIngredients);

Related

js - comparing 2 arrays of objects, and storing the identical and the unidentical results in new arrays

Made example arrays -
const arr = [
{
name: "q",
age: 10,
size: "M",
},
{
name: "w",
age: 10,
size: "S",
},
{
name: "e",
age: 10,
size: "M",
},
];
const arr2 = [
{
name: "q",
age: 10,
size: "M",
},
{
name: "w",
age: 10,
size: "S",
},
{
name: "i",
age: 10,
size: "S",
},
{
name: "x",
age: 10,
size: "S",
},
];
I want to compare the first array (arr) to the second one (arr2) by specific properties in the example case name and size.
If it's a match then I want to store the results in a new array and if it's unmatched then I want to store the results in another array, so I'll get 2 arrays at the end.
What I tried -
for (let j = 0; j < arr2.length; j++) {
for (let i = 0; i < arr.length; i++) {
const { name: name1, size: size1 } = arr[i];
const { name: name2, size: size2 } = arr2[j];
if (name1 === name2 && size1 === size2) {
x.push(arr.splice(i, 1)[0]);
break;
} else {
y.push(arr[i]);
}
}
}
Got in x -
[ { name: 'q', age: 10, size: 'M' }, { name: 'w', age: 10, size: 'S' } ]
Got in y -
[ { name: 'e', age: 10, size: 'M' },
{ name: 'e', age: 10, size: 'M' } ]
I should get in y -
[ { name: 'e', age: 10, size: 'M' } ]
Would love to get some help
Your inner loop cannot decide whether an element should be pushed to y, because not all values of arr2 have been iterated yet. Such a push can only happen when all those arr2 values have been considered.
As you don't remove the item from arr when it is pushed to y, it is no surprise it can be pushed a second time.
It is also problematic that you use splice in a loop over that same array. This means that indexes are skipped, and this could also be a source of wrong results.
One way to solve this, is to create a Set of the second array, of strings that uniquely define the name/size combination, for instance by joining them with a separator that will not occur in the size value. Then remains to iterate the first array and check if that name/size key is present in that set or not:
const arr = [{name: "q",age: 10,size: "M",},{name: "w",age: 10,size: "S",},{name: "e",age: 10,size: "M",},];
const arr2 = [{name: "q",age: 10,size: "M",},{name: "w",age: 10,size: "S",},{name: "i",age: 10,size: "S",},{name: "x",age: 10,size: "S",},];
const set = new Set(arr2.map(({name, size}) => size + "/" + name));
const x = [], y = [];
for (let obj of arr) {
(set.has(obj.size + "/" + obj.name) ? x : y).push(obj);
}
console.log("x:");
console.log(x);
console.log("y:");
console.log(y);

Javascript sort array of objects based on another array

I have an array of objects I need to sort based on another array objects. This is the given array that needs to be sorted:
const arr1 = [
{
id: 21,
name: 'Joey',
vehicle: 'car'
},
{
id: 6,
name: 'Kevin'
vehicle: 'car'
},
{
id: 10,
name: 'Luis'
vehicle: 'van'
}
]
And this is the array that is in the proper order:
const arr2 = [
{
id: 6,
name: 'Kevin'
},
{
id: 21,
name: 'Joey'
},
{
id: 10,
name: 'Luis'
}
]
There is no specific order to arr2 its just the data that comes back from my db. I basically just need to put the ids in arr1 in the same order as thet are in arr2.
Ive tried using findIndex and sort but I am very confused
that ?
const arr1 =
[ { id: 21, name: 'Joey', vehicle: 'car' }
, { id: 6, name: 'Kevin', vehicle: 'car' }
, { id: 10, name: 'Luis', vehicle: 'van' }
]
const arr2 =
[ { id: 6, name: 'Kevin' }
, { id: 21, name: 'Joey' }
, { id: 10, name: 'Luis' }
]
// Arr1 ordered..
const arr1_ord = arr2.map(a2=> arr1.find(x=>x.id===a2.id))
console.log( arr1_ord )
.as-console-wrapper {max-height: 100%!important;top:0}
Also, if there are only 2 items in arr2 I still want those elements that are missing to be at the end of the sorted arr1. Would this solve that?
I add add another case : arr2 element doesn't have a arr1 same id
const arr1 =
[ { id: 21, name: 'Joey', vehicle: 'car' }
, { id: 6, name: 'Kevin', vehicle: 'car' }
, { id: 12, name: 'George', vehicle: 'carriage' } // not in arr2
, { id: 10, name: 'Luis', vehicle: 'van' }
]
const arr2 =
[ { id: 6, name: 'Kevin' }
, { id: 21, name: 'Joey' }
, { id: 88, name: 'none' } // not in arr1
, { id: 10, name: 'Luis' }
]
// Arr1 ordered..
const arr1_ord = arr2.reduce((res, {id},i,{[i+1]:next})=>
{
let a1 = arr1.find(x=>x.id===id)
if (a1) res.push(a1) // if exist in arr1
if (next) return res
else return [...res, arr1.filter(r=>!res.some(z=>z.id===r.id))] // add the missing elements
},[])
console.log( arr1_ord )
.as-console-wrapper {max-height: 100%!important;top:0}
Array.prototype.sort can take in a custom comparison function to sort however you'd like it to.
The function takes in two arguments (firstValue, secondValue)
If that function returns a positive value, then secondValue goes before the firstValue, if it's 0 or negative, then firstValue is sorted before secondValue. First/second value are from the array you are sorting. In your case, you are sorting based on a different array, but that is fine since you can do that in your function.
You can do:
arr1.sort((firstValue, secondValue) => {
return findIdInArr2(firstValue.id) - findIdInArr2(secondValue.id);
});
Where you would have to define findIdInArr2 to find the index in arr2, and you can use Array.prototype.findIndex to solve that problem. Where findIndex similarly takes in a function to find the index of something in an array.
function findIdInArr2(id) {
const foundIndex = arr2.findIndex(function(obj) {
return obj.id === id;
});
// If not found, this will be -1. But that would sort all
// unfound objects at the beginning of the array.
// To place these objects at the end of the array, it needs to
// return a number higher than the rest. So return infinity.
return (foundIndex === -1) ? Infinity : foundIndex;
}
note: findIndex is not available in IE, so you'd need to add a polyfill if you are planning on supporting IE.

Question regarding swapping key/value of objects

I want to swap the key/value content of Jacob with the key/value content of Guillermo
I was able to swap Guillermo to Jacob but not the other way around.
This is my code which is only half correct:
let students = {
jacob: {
classes: ["math", "chemistry", "english"],
grade: 11,
age: 16,
},
guillermo: {
classes: ["history", "math", "physics"],
grade: 12,
age: 17,
},
};
let temp = students.jacob;
students.guillermo = temp;
let temp1 = students.guillermo;
students.jacob = temp1;
console.log(students)
You need to copy before re-assigning
let students = {
jacob: {
classes: ["math", "chemistry", "english"],
grade: 11,
age: 16,
},
guillermo: {
classes: ["history", "math", "physics"],
grade: 12,
age: 17,
},
};
let temp = students.jacob;
let temp1 = students.guillermo;
students.guillermo = temp;
students.jacob = temp1;
console.log(students)

Weird hiccup removing duplicates from an array

I'm running into a weird glitch. I have a bit of code where I'm running thru an array of arrays, grabbing a bunch of city names and concatenating them all together. I need to remove the duplicates from the finished list. This should be pretty simple. Use a count to figure out which city has more than one instance and then splice them out. My returned array isn't coming out right though and I'm not sure why. Can anyone spot what I'm doing wrong?
const input = [
{
name: "ACH2000",
year: 2005,
cities: ['Chicago', 'New York', 'Ames', 'Columbus'],
ages: [12, 32, 2, 51]
},
{
name: "FXG3000",
year: 2008,
cities: ['Chicago', 'Joliet', 'Plymouth', 'Dallas'],
ages: [12, 32, 2, 51]
},
{
name: "GTG1234",
year: 2012,
cities: ['Indy', 'Tampa', 'Houston', 'Dallas'],
ages: [12, 32, 2, 51]
}
];
function getUniqueCities(data){
let citiesInArray = data.map(function(item){ return item.cities });
let concatCities = [].concat.apply([], citiesInArray);
let count = {};
for(let i = 0; i< concatCities.length; i++) {
let num = concatCities[i];
count[num] = count[num] ? count[num]+1 : 1;
if(count[num] > 1){
console.log('bad',num);
concatCities.splice(num, 1);
} else {
console.log('good',num);
}
}
console.log(count);
console.log(concatCities);
}
getUniqueCities(input);
you can try something like this
var input = [
{
name: "ACH2000",
year: 2005,
cities: ['Chicago', 'New York', 'Ames', 'Columbus'],
ages: [12, 32, 2, 51]
},
{
name: "FXG3000",
year: 2008,
cities: ['Chicago', 'Joliet', 'Plymouth', 'Dallas'],
ages: [12, 32, 2, 51]
},
{
name: "GTG1234",
year: 2012,
cities: ['Indy', 'Tampa', 'Houston', 'Dallas'],
ages: [12, 32, 2, 51]
}
];
var citiesStats = {};
input.forEach(data =>
data.cities.forEach(city => {
if (!citiesStats[city]) {
citiesStats[city] = 0;
}
++citiesStats[city];
})
);
var cities = Object.keys(citiesStats);
// ["Chicago", "New York", "Ames", "Columbus", "Joliet", "Plymouth", "Dallas", "Indy", "Tampa", "Houston"]
console.log(cities);
// {"Chicago":2,"New York":1,"Ames":1,"Columbus":1,"Joliet":1,"Plymouth":1,"Dallas":2,"Indy":1,"Tampa":1,"Houston":1}
console.log(citiesStats);
As nnnnnn suggested splicing inside the loop is messing up the indices in the array.
If you can use Set, here is a solution:
Array.from(new Set(concatCities))
Here is a link to fiddle.

return array of object javascript

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 .

Categories