Find object in array? - javascript

Imagine I've got an array of objects like so (dummy code):
const chosenBets = [{...}, {...}] // 2 items
And I want to delete a specific item from the array:
{id: 0, // is unique
label: 1,
odd: 1.33,
oddIndex: 0,
team_home: "Liverpool",
team_away: "Sheffield United",
matchCardIndex: 0,}
So that array is now:
const chosenBets = [{...}] // 1 items
How would I achieve this?

You can use array filter
const chosenBets = [{
id: 0, // is unique
label: 1,
odd: 1.33,
oddIndex: 0,
team_home: "Liverpool",
team_away: "Sheffield United",
matchCardIndex: 0
}, {
id: 1, // is unique
label: 1,
odd: 1.33,
oddIndex: 0,
team_home: "Liverpool",
team_away: "Sheffield United",
matchCardIndex: 0
}];
const filteredData = chosenBets.filter(item => item.id === 1);
console.log(filteredData);

You can use splice
var a = [{
id: 0, // is unique
label: 1,
odd: 1.33,
oddIndex: 0,
team_home: "Liverpool",
team_away: "Sheffield United",
matchCardIndex: 0,
},
{
id: 0, // is unique
label: 11,
odd: 1.33,
oddIndex: 0,
team_home: "Liverpool",
team_away: "Sheffield United",
matchCardIndex: 0,
}
]
a.forEach((e, j) => {
if (e.label == 1)
a.splice(j, 1);
})
console.log(a)

If you want to delete a specific and unique object, I would do something like:
let chosenBets = [{
id: 0, // is unique
label: 1,
odd: 1.33,
oddIndex: 0,
team_home: "Liverpool",
team_away: "Sheffield United",
matchCardIndex: 0
}, {
id: 1, // is unique
label: 1,
odd: 1.33,
oddIndex: 0,
team_home: "Liverpool",
team_away: "Sheffield United",
matchCardIndex: 0
}];
let index = chosenBets.findIndex(({id}) => id === 1);
// if you want to mutate the original array, otherwise use `slice`
chosenBets.splice(index, 1);
console.log(chosenBets);
filter is better if you want to remove a group of elements, not just one. The reason is, it keeps going to iterate all the elements of the array, so it always iterate the whole array, even if the element you want to remove is the first one.
Using findIndex you just iterate until you find the element, and then return the index: so as average, it does less cycle.

Related

Updating an array of objects properties based on another object

I want to update an arrays of objects (league table) based on another array of object (match result) by finding id from the two teams and update the stats on the league table,
Just like how football(soccer) league table works.
This is how the league standing looks
let leagueStandings = [
{id:'49e93e0d', played: 0, scored: 0, conceded: 0, won: 0, drawn: 0, lost: 0},
{id:'24e5ddb8', played: 0, scored: 0, conceded: 0, won: 0, drawn: 0, lost: 0}
]
I get this match result array of objects for both teams, which I need to update on the league standings..
let matchResult = [
{ id: '49e93e0d', scored: 2, conceded: 1, win: true, draw: false },
{ id: '24e5ddb8', scored: 1, conceded: 2, win: false, draw: false }
]
So I came up with this code
function updateStandings(match) {
let team;
match.forEach(prop => { //loop both teams in result and update their respective stats
team = leagueStandings.find(team => team.id === prop.id); // find the team to update by id
team.played++
team.scored += prop.scored
team.conceded += prop.conceded
team.goalDifference += (prop.scored - prop.conceded)
if (prop.win) team.won++
if (prop.draw) team.drawn++
if (!prop.win && !prop.draw) team.lost++
});
}
updateStandings(matchResult)
// outputs the expected the result
[
{ id: '49e93e0d', played: 1, scored: 2, conceded: 1, won: 1, drawn: 0, lost: 0 },
{ id: '24e5ddb8', played: 1, scored: 1, conceded: 2, won: 0, drawn: 0, lost: 1 }
]
Which actually works and does the job, however I think there is better way to do it? also the league standings array will contain large nums of teams, so I'm not sure if it's the best way?
expected output
[
{ id: '49e93e0d', played: 1, scored: 2, conceded: 1, won: 1, drawn: 0, lost: 0 },
{ id: '24e5ddb8', played: 1, scored: 1, conceded: 2, won: 0, drawn: 0, lost: 1 }
]
Full code HERE
The find() function in your solution will go through every leagueStandings item to match the id
Because leagueStandings is unordered on average it has to loop though half the items before it finds a match.
This can be fixed by indexing by ID
consider using this structure for leagueStandings:
let leagueStandings = {
'49e93e0d': {played: 0, scored: 0, conceded: 0, won: 0, drawn: 0, lost: 0},
'24e5ddb8': {played: 0, scored: 0, conceded: 0, won: 0, drawn: 0, lost: 0}
}
Now you can change this line:
team = leagueStandings.find(team => team.id === prop.id);
to this:
team = leagueStandings[prop.id];
and do an indexed lookup

Count the Number of Elements with the same Value in a Row?

Let's assume I have the following data structure:
const Table = [
[
{
"id": "258ce34d-cba6-44a8-bdb9-e436d18701aa",
"seat": 1,
"group": 1
},
{
"id": "60adc321-c7e3-4d34-963a-e09dc53345d0",
"seat": 2,
"group": 1
}
],
[
{
"seat": "empty",
"group": 0
},
{
"seat": "empty",
"group": 0
}
],
[
{
"id": "c8c3c973-351b-4314-8096-a6d12c7b01fb",
"seat": 5,
"group": 3
},
{
"id": "1c256b45-b3f3-49cc-b7e4-29967594c4fb",
"seat": 6,
"group": 3
}
],
[
{
"seat": "empty",
"group": "empty"
},
{
"seat": 0,
"group": 0
}
],
[
{
"id": "63469f95-7deb-483c-ad7d-cf0cbdc191b1",
"seat": 9,
"group": 5
},
{
"id": "e77c8fb3-2e0b-43f7-a9ca-1bbd8143ba59",
"seat": 10,
"group": 5
}
]
]
It is an array that represents a table in a restaurant. In this array there are other arrays representing the groups of guests.
As you can see there are two free slots at the table.
The task now is to write a function that calculates how many seats are free in a row. Input is this array and output should be a number. So in this case MaxFreeSeatsinRow(Table) => 2
For example, if a group of 4 people arrives, there are enough seats but not in one row.
Does anyone have an idea how to calculate this? Thanks for your help!
According to your comments, this is really just a matter of flattening the structure to an array of seats and then finding the longest streak of empty seats.
We can write a general-purpose longestStreak function which accepts a predicate function and returns a function which accepts a list of elements, and then tests each element against that predicate, updating the length of the current streak and possibly the maximum value when it matches, and resetting the current streak to zero when it doesn't.
Our main function, canSeat accepts a Table, and supplies to longestStreak a predicate which tests if a seat has value of 0 or "empty" (note: do you really want to support both?) and then supplies to the resulting function an extract of the Table selecting all the seats in it.
const longestStreak = (pred) => (xs) =>
xs .reduce (
({max, curr}, x) => pred (x)
? {max: curr >= max ? curr + 1 : max, curr: curr + 1}
: {max, curr: 0}
, {max: 0, curr: 0}
) .max
const canSeat = (table) => longestStreak
(s => s == 0 || s == "empty")
(table .flatMap (groups => groups .map (g => g .seat)))
const Table = [[{id: "258ce34d-cba6-44a8-bdb9-e436d18701aa", seat: 1, group: 1}, {id: "60adc321-c7e3-4d34-963a-e09dc53345d0", seat: 2, group: 1}], [{seat: "empty", group: 0}, {seat: "empty", group: 0}], [{id: "c8c3c973-351b-4314-8096-a6d12c7b01fb", seat: 5, group: 3}, {id: "1c256b45-b3f3-49cc-b7e4-29967594c4fb", seat: 6, group: 3}], [{seat: "empty", group: "empty"}, {seat: 0, group: 0}], [{id: "63469f95-7deb-483c-ad7d-cf0cbdc191b1", seat: 9, group: 5}, {id: "e77c8fb3-2e0b-43f7-a9ca-1bbd8143ba59", seat: 10, group: 5}]]
console .log (canSeat (Table))
If I understood correctly, you'd like to know of the number of free seats per nested array?
If so, I think it can be pretty straightforward using a functional approach:
const freeSeats = Table.map(row => {
return row.filter(place => place.seat === "empty").length
})
// freeSeats = [0, 2, 0, 2, 0]
Then it's easy to get the maximum grouped seats:
Math.max(...freeSeats)

Count occurences of an object field in an array and add it as an additional key

I want to create an array of object like this :
array_1 :
array(0, 0, 0, 1, 0, 1, 0, 1, 1);
object_2 :
obj: [
{
id: 0,
fonction: 'hey'
},
{
id: 1,
fonction: 'hi'
}
]
So, I want the following output :
result :
obj: [
{
id: 0, // id of object_2
max: 5, // number of id value in array_1
value: 0, // add an empty value
fonction: 'hey' // fonction text in oject_2
},
{
id: 1,
max: 4,
value: 0,
fonction: 'hi'
}
]
Thanks for your help
You can just map your existing object, and count the ids inside your array using the filter + length option
const arr = [0, 0, 0, 1, 0, 1, 0, 1, 1];
const target = [
{
id: 0,
fonction: 'hey'
},
{
id: 1,
fonction: 'hi'
}
];
console.log( target.map( item => ({
...item,
max: arr.filter( v => item.id === v ).length,
value: 0
}) ) );

How can I get objects from array with specific id compares from another array numbers

I need to compare id objects array from a firstArray and array numbers (secondArray) and return a new array with objects from the first array which id number exists in the second array.
So at the end, I want a new array with objects with id 39 and 41.
Actually I find something like this:
const result = arr2.filter(o => arr1.find(x => x.id === o));
const arr1 =
"blocks": [
{
"id": 1,
"functions": [ 0, 1 ]
},
{
"id": 39,
"functions": [ 0, 1, 3, 4 ]
},
{
"id": 41,
"functions": [ 0, 1 ]
}
]
const arr2 = [39, 41]
You can use includes() function during filtering. Includes() works like in array function.
const arr1 =
[ {
"id": 1,
"functions": [ 0, 1 ] },
{
"id": 39,
"functions": [ 0, 1, 3, 4 ]
},
{
"id": 41,
"functions": [ 0, 1 ]
}
]
const arr2 = [39, 41]
const result = arr1.filter(o => arr2.includes(o.id));
console.log(result)
You can create a Map to see whether there is an item of Map exists in filtering array. Getting an item from Map method is O(1):
const blocks = [
{
"id": 1,
"functions": [
0,
1
]
},
{
"id": 39,
"functions": [
0,
1,
3,
4
]
},
{
"id": 41,
"functions": [
0,
1
]
}
];
const arr2 = [39, 41];
const arr2Maps = new Map(arr2.map(a=>[a, a]));
const result = blocks.filter(o => arr2Maps.get(o.id));
console.log(result)
In addition, you can use filter and some methods. However, some method has O(n):
const blocks = [
{
"id": 1,
"functions": [
0,
1
]
},
{
"id": 39,
"functions": [
0,
1,
3,
4
]
},
{
"id": 41,
"functions": [
0,
1
]
}
];
const arr2 = [39, 41]
const result = blocks.filter(o => arr2.some(a=> a ==o.id ));
console.log(result)

Use dictionary to filter javascript data object

Say I have a filter:
filter = [ {key: "pl", value: 3}, {key: "sh", value: 2} ]
I want to filter the following javascript object with the above filter conditions:
var data = [
{title: "The Uncertainty of the Poet ",
pl: 3,
si: 2,
va: 3,
te: 0,
co: 0,
or: 4,
sh: 2,
po: 0,
li: 0,
ar: 5
},
{
title: "Direction",
pl: 4,
si: 3,
va: 1,
te: 3,
co: 0,
or: 3,
sh: 2,
po: 0,
li: 0,
ar: 5
}
...
]
I tried the following with no luck:
var result = data.filter(function(d){
for (item in filter) {
return d.key==d.value;
}
Just another potential option to check if the object meets all the criteria:
data.filter(function(obj) {
return filter.reduce(function(a, f) {
return a && (obj[f.key] === f.value);
}, true);
});
That will work without having to check for hasOwnProperty because of the use of reduce. If you wanted to check for if any of the filter conditions are true, you would change it to
data.filter(function(obj) {
return filter.reduce(function(a, f) {
return a || (obj[f.key] === f.value);
}, false);
});
You can do this way as well:
var filters = [{key: "pl", value: 3}, {key: "sh", value: 2}]
var data = [
{
title: "The Uncertainty of the Poet ",
pl: 2,
si: 2,
va: 3,
te: 0,
co: 0,
or: 4,
sh: 3,
po: 0,
li: 0,
ar: 5
},
{
title: "Direction",
pl: 3,
si: 3,
va: 1,
te: 3,
co: 0,
or: 3,
sh: 2,
po: 0,
li: 0,
ar: 5
}
]
var result = data.filter((item) => {
for(let i = 0; i < filters.length; ++i) {
let filter = filters[i];
if(item[filter.key] && item[filter.key] === filter.value) {
return true;
}
}
return false;
});
If you want it to match one or the other values, this will work:
match = [ {key: "pl", value: 3}, {key: "sh", value: 2} ]
var result = data.filter(function(d) {
return d.pl === match[0]['value'] || d.sh === match[1]['value']
})
I've changed the name of the array to match to avoid confusion.
You aren't going deep enough with your for in. It is looping over the array and not working with each object in the array
Can use Array#every() to make sure every object in filter array has match in the data object
// filter main data
var result = data.filter(function(dataObj){
// check if all proprties within filter array are a match
return filter.every(function(filterObj){
//compare value of property found in filterObject with value
return dataObj[filterObj.key] === filterObj.value
})
})
console.log(result)
<script>
var filter = [ {key: "pl", value: 2}, {key: "sh", value: 3} ]
var data = [{
title: "The Uncertainty of the Poet ",
pl: 2,
si: 2,
va: 3,
te: 0,
co: 0,
or: 4,
sh: 3,
po: 0,
li: 0,
ar: 5
},
{
title: "Direction",
pl: 4,
si: 3,
va: 1,
te: 3,
co: 0,
or: 3,
sh: 2,
po: 0,
li: 0,
ar: 5
}
]
</script>

Categories

Resources