I'm sure it's somewhere inside the LoDash docs, but I can't seem to find the right combination.
var users = [{
id: 12,
name: 'Adam'
},{
id: 14,
name: 'Bob'
},{
id: 16,
name: 'Charlie'
},{
id: 18,
name: 'David'
}
]
// how do I get [12, 14, 16, 18]
var userIds = _.map(users, _.pick('id'));
Since version v4.x you should use _.map:
_.map(users, 'id'); // [12, 14, 16, 18]
this way it is corresponds to native Array.prototype.map method where you would write (ES2015 syntax):
users.map(user => user.id); // [12, 14, 16, 18]
Before v4.x you could use _.pluck the same way:
_.pluck(users, 'id'); // [12, 14, 16, 18]
In the new lodash release v4.0.0 _.pluck has removed in favor of _.map
Then you can use this:
_.map(users, 'id'); // [12, 14, 16, 18]
You can see in Github Changelog
With pure JS:
var userIds = users.map( function(obj) { return obj.id; } );
And if you need to extract several properties from each object, then
let newArr = _.map(arr, o => _.pick(o, ['name', 'surname', 'rate']));
Simple and even faster way to get it via ES6
let newArray = users.flatMap(i => i.ID) // -> [ 12, 13, 14, 15 ]
If you are using native javascript then you can use this code -
let ids = users.map(function(obj, index) {
return obj.id;
})
console.log(ids); //[12, 14, 16, 18]
const users = [{
id: 12,
name: 'Adam'
},{
id: 14,
name: 'Bob'
},{
id: 16,
name: 'Charlie'
},{
id: 18,
name: 'David'
}
]
const userIds = _.values(users);
console.log(userIds); //[12, 14, 16, 18]
This will give you what you want in a pop-up.
for(var i = 0; i < users.Count; i++){
alert(users[i].id);
}
Related
I would like to map over an array of objects. If the id of each object matches the id from another array then I want to return the movie name.
I have seen other threads about this and have used .map and .find however for some reason my code does not return the result I want.
Find object by id in an array of JavaScript objects
const moviesNamesAndGenres = [
{id: 28, name: "Action"},
{id: 12, name: "Adventure"},
{id: 14, name: "Animation"}
]
const genreIds = [14, 28, 13];
const test = genreIds.map((genreId) => {
const matchedGenres = moviesNamesAndGenres.find((movieObj) => {
return movieObj.id === genreId
})
return matchedGenres // this returns the matching objects, cool
})
At this point I have the following as two objects in the array for ids that matched.
{ id: 14, name: 'Animation' }
{ id: 28, name: 'Action' }
undefined
I would now like to return the name for each object
here is my code attempt:
const result = test.map((el) => {
return el.name
})
console.log(result)
Now I get:
TypeError: Cannot read property 'name' of undefined
could someone help me understand why?
You can first filter out elements for which no matching object was found.
const moviesNamesAndGenres = [
{id: 28, name: "Action"},
{id: 12, name: "Adventure"},
{id: 14, name: "Animation"}
]
const genreIds = [14, 28, 13];
const test = genreIds.map((genreId) => {
const matchedGenres = moviesNamesAndGenres.find((movieObj) => {
return movieObj.id === genreId
})
return matchedGenres // this returns the matching objects, cool
})
const result = test.filter(Boolean).map((el) => {
return el.name
})
console.log(result)
The error is clear. You are trying to access a property of an undefined object. There is no match between the object with id:14 and the number 13 of the Array.
You can use the function Array.prototype.map over the array genreIds, extract the name, and finally filter out the undefined values (those not found objects).
const moviesNamesAndGenres = [ {id: 28, name: "Action"}, {id: 12, name: "Adventure"}, {id: 14, name: "Animation"}],
genreIds = [14, 28, 13],
result = genreIds.map(g => (moviesNamesAndGenres.find(m => m.id === g) || {}).name).filter(Boolean);
console.log(result);
I am trying to loop through an array of objects and store it on the table, Here is the sequence of events my code is doing.
Grab values from a JSON file [done]
Store them in my code as array of objects like so[done]:
var results =
{name : [], goals: [], assists: [] , team: []};
3.Display the content in a table where I want the format to be below:
Name Goals Assists Team
Player 1 Name Player 1 Goals Player 1 Assists Player 1 Team
Picked up object containing arrays looks like so:
{
assists: [4, 2, 2, 9, 1, 7, 3, 6, 4, 6, 3, 1, 2, 7, 3, 1, 18, 3, 10, 9],
goals: [23, 20, 19, 19, 17, 16, 16, 16, 15, 15, 14, 13, 13, 12, 12, 11, 11, 11, 10, 10],
name: ['J. Vardy', 'P. Aubameyang', 'D. Ings', 'Mohamed Salah', 'R. Sterlin', 'S. Mané ', 'S. Agüero', , , , , , , , , , , ,],
team: ['Leicester', 'Arsenal', 'Southampton', 'Liverpool', 'Manchester City', 'Liverpool', 'Manchester City', , , , , , , , , , , ,],
}
My code sample obtain this is using the for each functionality as below but my results display nothing, Full code below: [in progress]
var stats, table;
var results =
{name : [], goals: [], assists: [] , team: []};
//We need to initiate a request to read the json file
$.getJSON('data/topscores.json')
.done(function(data){ // Once done do the below
$.each(data, function(keyIndex) { //Loop through the JSon, grab all values and store in obj array
results.name[keyIndex] = (data[keyIndex].player.name)
stats = data[keyIndex].statistics
results.goals[keyIndex] = (stats[0].goals.total)
results.assists[keyIndex] = (stats[0].goals.assists)
results.team[keyIndex] = (stats[0].team.name)
});
table = document.getElementById('rank').getElementsByTagName('tbody')[0] //Grabbing first contents of table body
for (var key in results.name.length) {
var row = document.createElement('tr'); //insert 20 rows beginning of the loop
Object.values(res).forEach(text => { //Loop through object array and store values in respective table cells
var cell = document.createElement('td')
var textNode = document.createTextNode(text)
cell.appendChild(textNode)
row.appendChild(cell)
});
table.appendChild(row)
}
}) //End of JSON function
Any help would be appreciated on how i can display the results array of objects into my table cells
If you have an element <table></table> and an object data containing your game data, you can display it in the table like so:
<!DOCTYPE html>
<html>
<body>
<table></table>
<script>
const data = {
assists: [4, 2, 2, 9, 1, 7, 3, 6, 4, 6, 3, 1, 2, 7, 3, 1, 18, 3, 10, 9],
goals: [23, 20, 19, 19, 17, 16, 16, 16, 15, 15, 14, 13, 13, 12, 12, 11, 11, 11, 10, 10],
name: ['J. Vardy', 'P. Aubameyang', 'D. Ings', 'Mohamed Salah', 'R. Sterlin', 'S. Mané ', 'S. Agüero', , , , , , , , , , , ,],
team: ['Leicester', 'Arsenal', 'Southampton', 'Liverpool', 'Manchester City', 'Liverpool', 'Manchester City', , , , , , , , , , , ,],
};
const titles = ['name', 'goals', 'assists', 'team'];
const createElement = document.createElement.bind(document);
const querySelector = document.querySelector.bind(document);
const table = querySelector('table');
const titleTr = createElement('tr');
table.append(titleTr);
titles.forEach(title => {
const th = createElement('th');
th.textContent = title.replace(/\w/, l => l.toUpperCase());
titleTr.append(th);
});
Object.keys(Object.values(data)[0]).forEach(i => {
const tr = createElement('tr');
titles.forEach(title => {
const td = createElement('td');
td.textContent = data[title][i];
tr.append(td);
});
table.append(tr);
});
</script>
</body>
</html>
The obcious issue I see is your iteration over json results. The for-in loop is for iterating over object's properties only and you want to iterate over an array results.name.
Even if you were iterating over an object, your for loop syntax doesn't make much sense (iterating over array's length?!).
Try it like this: for (let i=0; i<results.name.length; i++).
Also, what is res in Object.values(res)?!
I have a single dimensional and an array of Objects
array1 = [1, 3, 15, 16, 18];
array2 = [
{ id: 1, dinner : pizza },
{ id: 15, dinner : sushi },
{ id: 18, dinner : hummus }
]
I'm trying to remove values from array1 that are not in array2 based on the id.
I know how to remove in two single dimensional arrays but I'm unable to modify the code to remove when array2 is an array of Objects.
const array1 = array1.filter(id => array2.includes(id));
Any help would be appreciated.
Both arrays are single dimension arrays.
use .some() function along with .filter() function to remove those numbers from array1 which are not present as id in any of the objects in array2
const array1 = [1, 3, 15, 16, 18];
const array2 = [
{ id: 1, dinner : 'pizza' },
{ id: 15, dinner : 'sushi' },
{ id: 18, dinner : 'hummus' }
]
const filteredArr = array1.filter(v => array2.some(o => v == o.id));
console.log(filteredArr);
You can map all Ids and then filter
var array1 = [1, 3, 15, 16, 18];
var array2 = [
{ id: 1, dinner : "pizza" },
{ id: 15, dinner : "sushi" },
{ id: 18, dinner : "hummus" }
]
const Ids = array2.map(i=> i.id);
var res = array2.filter(i => Ids.includes(i.id));
var res2 = Ids.filter(i => array1.includes(i))// Or, just to get common Ids
console.log(res)
console.log(res2)
But I suggest you should use reduce to avoid two passes:
var array1 = [1, 3, 15, 16, 18];
var array2 = [
{ id: 1, dinner : "pizza" },
{ id: 15, dinner : "sushi" },
{ id: 18, dinner : "hummus" }
]
var res = array2.reduce((acc, {id})=>{
if(array1.includes(id)){
acc = [...acc, id]
}
return acc
},[]);
console.log(res)
I have two arrays:
arr1 = [name, speed, power, energy];
arr2 = [
[Ed, 10, 20, 30],
[Robert, 15, 25, 35],
[Paul, 8, 18, 28]
];
How can I combine the two array's to an array of objects, using the first array for keys and the second one for values?
arr3 = [
{
name: "Ed",
speed:"10",
power:"20",
energy:"30"
},
{
name: "Robert",
speed:"15",
power:"25",
energy:"35"
},
{
name: "Paul,
speed:"8",
power:"18",
energy:"28"
}
];
You can simply create an array of objects using map
arr2.map(row => {
const name = item[0];
const speed = item[1];
const power = item[2];
const energy = item[3];
return { name, speed, power, energy }
})
Running this on your given arr2 gives the following result
var arr2 = [['Ed', 10, 20, 30],['Robert', 15, 25, 35],['Paul', 8, 18, 28]];
var arr3 = arr2.map(row => {
const name = item[0];
const speed = item[1];
const power = item[2];
const energy = item[3];
return { name, speed, power, energy }
});
console.log(arr3)
// arr3 = [
// {name: "Ed", speed:10, power:20, energy:30},
// {name: "Robert", speed:15, power:25, energy:35},
// {name: "Paul", speed:8, power:18, energy:28}
// ]
Firstly, I am assuming the tokens name, speed, power, energy are actually strings and you forgot to include the quotes.
The Object.fromEntries method takes an array of tuples (two-item arrays) and converts it into an object.
If we zip the keys from arr1 with the values from each array in arr2, we can acheive the desired mapping.
arr1 = ["name", "speed", "power", "energy"];
arr2 = [["Ed", 10, 20, 30],["Robert", 15, 25, 35],["Paul", 8, 18, 28]];
arr3 = arr2.map(objArr =>
Object.fromEntries(arr1.map((key, i) =>
[key, objArr[i]] // key-value tuple
))
)
console.log(arr3);
Ruby has this really useful method called zip, so you want basically that for each of arr2 but in JavaScript. In other words, zip arr1 keys with each person's properties.
Below is a snippet that implements a basic zip function and then uses it to create the object in the format you're looking for:
arr1 = ["name", "speed", "power", "energy"];
arr2 = [
["Ed", 10, 20, 30],
["Robert", 15, 25, 35],
["Paul", 8, 18, 28],
];
Array.prototype.zip = function(a) {
return this.map((k, i) => [k, a[i]]);
};
arr3 = arr2.map(p => Object.fromEntries(arr1.zip(p)));
console.log(arr3);
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.