JS array : filter() with map() vs forEach() [closed] - javascript

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 12 months ago.
Improve this question
Which is more optimized way .filter() + .map() OR .forEach() ?
Here is a sample array of objects:
var personnel = [
{
id: 5,
name: "Luke Skywalker",
pilotingScore: 98,
shootingScore: 56,
isForceUser: true,
},
{
id: 82,
name: "Sabine Wren",
pilotingScore: 73,
shootingScore: 99,
isForceUser: false,
},
{
id: 22,
name: "Zeb Orellios",
pilotingScore: 20,
shootingScore: 59,
isForceUser: false,
},
{
id: 15,
name: "Ezra Bridger",
pilotingScore: 43,
shootingScore: 67,
isForceUser: true,
},
{
id: 11,
name: "Caleb Dume",
pilotingScore: 71,
shootingScore: 85,
isForceUser: true,
},
];
And let say we want to get the final array giving only name and id where isForceUser=true
[ { id: 5, name: 'Luke Skywalker' }, 
{ id: 15, name: 'Ezra Bridger' }, 
{ id: 11, name: 'Caleb Dume' } ] 
Now there are 2 ways ti solve it :
By using .filter()+.map(), as shown below:
var APersonnel = personnel
.filter((person) => person.isForceUser)
.map((person) => ({ id: person.id, name: person.name }));
By using .forEach() and pushing a new object:
var BPersonnel = [];
personnel.forEach((person) => {
if (person.isForceUser) {
BPersonnel.push({ id: person.id, name: person.name });
}
});
Which one of the solutions defined above is better and why?

These are not the things you should seek performance improvements in. You are talking about 'personnel' here. Which is a fairly limited array set, I imagine. If you are having performance issues, I suggest you use the chrome dev performance tab to see what's causing it.
To answer your question, filter + map is semantically easier for the eye, which again is a personal opinion. Strictly performance wise the forEach is faster, where most likely a basic of for loop is even faster. But again, these are a few milliseconds we are talking about. Which does not justify the cost of rewriting :)
Another way can be to use reduce, less code, and only one loop:
const APersonnel = personell.reduce((acc, person) => {
if (person.isForceUser) {
acc.push({ id: person.id, name: person.name });
}
return acc;
}, []);

The best way is using foreach. Because map and filter are going to create two arrays. foreach doesn't create arrays. So foreach is the best one. look at those statements bellow,
The filter() method creates a new array with all elements that pass the test implemented by the provided function.
The map() method creates a new array with the results of calling a provided function on every element in the calling array.

I could be wrong, but I'm guessing forEach would be better.
In the first scenario, you are looping across 5 items, and then again across 3 items.
In the second scenario you are just looping across 5 items. And the if in the foreach is effectively being done in the filter anyway.
There may be an exception if you're working with an extremely large set of data because you would have both arrays in memory, but for anything short of that, I would recommend forEach

Related

How to get second duplicate value rather than first value from JSON Array in React JS using lodash? [duplicate]

This question already has an answer here:
Lodash uniqBy update the latest value
(1 answer)
Closed 9 months ago.
I am working on one project where I need to remove duplicate values from JSON array object with some specification in react JS. I have tried to remove using _.uniqBy but in the output it took very first value from duplicate value which is I don't want.
Suppose You have an array JSON like:
[ { id: 1, name: 'bob' }, { id: 2, name: 'bill' }, { id: 1, name: 'alice' } ]
using _.uniqBy I got [ { id: 1, name: 'bob' }, { id: 2, name: 'bill' }] this output.
but I want [ { id: 2, name: 'bill' }, { id: 1, name: 'alice' } ] this output.
As you can see I want output whose name is alice not bob along with id:1.
Can anyone help me?
Thank you.
My first thought is to use a reduce, and shove the items in a map, then get the values:
Object.values(items.reduce((map, item) => ({ ...map, [item.id]: item }), {}))
This is probably not very efficient though if you're dealing with large arrays of have performance concerns.
It's a quick and dirty one-liner. If you want something more efficient I'd take a look at the lodash source code and tweak it to your needs or write something similar:
https://github.com/lodash/lodash/blob/2f79053d7bc7c9c9561a30dda202b3dcd2b72b90/.internal/baseUniq.js

delete and modify properties in array inside json object [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 12 months ago.
Improve this question
Given the following JSON:
const myJson = {
id: 8,
active: true,
invoice: "2022/1001",
invoiceDate: "2022-02-02",
clientId: 1,
storeId: 1,
total: 76.95,
itens: [
{
id: 11,
quantity: 2,
price: 12.10,
total: 24.20,
productId: 1,
invoiceId: 8
},
{
id: 12,
quantity: 5,
price: 10.55,
total: 52.75,
productId: 2,
invoiceId: 8
}
]
};
I need a simple way to remove two attributes from the each item inside the 'itens' array, the properties are 'id' and 'invoiceId'. I also need to recalculate the 'total', coz I do not trust totally the source of the information, I rather multiply 'quantity' by 'price' myself.
I've produced this rather naive code:
myJson.itens.forEach(item => {
item.total =
item.quantity *
item.price;
delete item.id;
delete item.invoiceId;
});
And it works rather fine, however, no way that it must be it. Looks too lame and laborious to me. I'm exhausted googling for better ways of doing it.
Can it be done better?
Rather than mutating the original data, you could map it to a new object
const myJson = {"id":8,"active":true,"invoice":"2022/1001","invoiceDate":"2022-02-02","clientId":1,"storeId":1,"total":76.95,"itens":[{"id":11,"quantity":2,"price":12.1,"total":24.2,"productId":1,"invoiceId":8},{"id":12,"quantity":5,"price":10.55,"total":52.75,"productId":2,"invoiceId":8}]}
const newObject = {
...myJson, // keep the rest but map "itens"
itens: myJson.itens.map(({ id, invoiceId, ...iten }) => ({
...iten, // everything except "id" and "invoiceId"
total: iten.quantity * iten.price // recalc total
}))
}
console.log("newObject:", newObject)
.as-console-wrapper { max-height: 100% !important; }

Javascript object as a type of mini database?

Is it possible to use a JavaScript object as a type of mini database? I often find myself needing a kind of database structure when I'm coding in JS but it feels like overkill to use an actual database like MySQL (or similar).
As an example, let's say I need to structure this data as a JS object:
Object idea: Stuff to sell
Items to sell: The junk in the garage
Object structure: List all items including item name, item condition, and item value
In order to make this into a JS object I would maybe write:
var stuffToSell = {};
Then my first item would maybe look like:
var stuffToSell = {
item : "Coffee Maker",
condition : "Good",
price : 5
};
Now to me this seems like I'm on the right track, until I come to add another item and I end up having to use the properties item, condition, and price again in the same JS object — which feels wrong? — or is it?? At this point my brain keeps shouting the word "ARRAY!" at me but I just can't see how I can use an array inside the object, or an object inside an array to achieve what I want.
My end goal (in this simplified example) is to be able to then use object-oriented syntax to be able to access certain items and find out specific information about the item such as price, condition etc. For example if I want to know the price of the "coffee maker" I would like to write something like:
stuffToSell["coffee maker"].price
...and then the result above should be 5.
I feel like I'm on the right track but I think I'm missing the array part? Could someone please tell me what I'm missing or maybe what I'm doing completely wrong! And also if it is wrong to have duplicate property names in the same JS object? For example, is it okay to have:
var stuffToSell = {
item : "Coffee Maker",
price : 5,
item : "Mountain Bike",
price : 10,
item : "26 inch TV",
price : 15
};
...it seems wrong because then how does JS know which price goes with which item??
Thanks in advance :)
You're definitely on the right track!
A lot of people will refer to what you're talking about as a hash.
Here's my suggested structure for you:
var store = {
coffee_maker: {
id: 'coffee_maker',
description: "The last coffee maker you'll ever need!",
price: 5,
},
mountain_bike: {
id: 'mountain_bike',
description: 'The fastest mountain bike around!',
price: 10,
},
tv: {
id: 'tv',
description: 'A big 26 inch TV',
price: 15,
},
}
Having a structure like that will let you do this:
store.mountain_bike.price // gives me 10
Need an array instead, say for filtering or looping over?
Object.keys gives you an Array of all the object's keys in the store ['coffee_maker', 'mountain_bike', 'tv']
// Now we just have an array of objects
// [{id: 'coffee_maker', price: 5}, {id: 'mountain_bike', price: 10} ...etc]
var arr = Object.keys(store).map(el => store[el])
Need to just filter for items that are less than 10?
This will give us an array of products less than 10:
// gives us [{id: 'coffee_maker', price: 5}]
var productsUnder10 = arr.filter(el => el.price < 10)
These techniques can be chained:
var productsOver10 = Object.keys(store)
.map(el => store[el])
.filter(el => el.price > 10)
Need to add a product?
store['new_product'] = {
id: 'new_product',
description: 'The Newest Product',
price: 9000,
}
Here's another way, which would be good to start getting used to.
This is a 'safe' way to update the store, read up on immutability in javascript to learn about it
store = Object.assign({}, store, {
'new_product': {
id: 'new_product',
description: 'The Newest Product',
price: 9000,
}
})
...and another way, that you should also read up on and start using:
This is the object spread operator, basically just an easier way to work with immutable structures
store = {
...store,
'new_product': {
id: 'new_product',
description: 'The Newest Product',
price: 9000,
}
}
Resources
JavaScript Arrow Functions
Object and Array Spread Syntax
Immutable Javascript using ES6 and beyond
You can actually use json or create an array of objects.If using a separate file to store the objects, first load the file. Use array filter method to get an new array which matches the filter condition , like you want to get the item with id 1. This will return an array of objects.
var dict = [{
'id': 1,
'name': 'coffee-mug',
'price': 60
},
{
'id': 2,
'name': 'pen',
'price': 2
}
]
function getItemPrice(itemId) {
var getItem = dict.filter(function(item) {
return item.id === itemId
});
return getItem[0].price;
}
console.log(getItemPrice(1))
JSON objects don't support repeated keys, so you need to set unique keys.
Put an id as your key to group your items:
var stuffToSell = {
'1': {
item: "Coffee Maker",
price: 5
},
'2': {
item: "Mountain Bike",
price: 10
}
.
.
.
}
Now you can access the item's price very fast.
Look at this code snippet (Known Ids)
var stuffToSell = {
'1': {
item: "Coffee Maker",
price: 5
},
'2': {
item: "Mountain Bike",
price: 10
},
'3': {
item: "26 inch TV",
price: 15
}
};
let getPrice = (id) => stuffToSell[id].price;
console.log(getPrice('1'));
See? the access to your items it's fast and your code follows a readable structure.
Look at this code snippet (Item's name as key)
var stuffToSell = {
'Coffee Maker': {
price: 5
},
'Mountain Bike': {
price: 10
},
'26 inch TV': {
price: 15
}
};
let getPrice = (id) => stuffToSell[id].price;
console.log(getPrice('Coffee Maker'));
Look at this code snippet (Item's name: price)
var stuffToSell = {
'Coffee Maker': 5,
'Mountain Bike': 10,
'26 inch TV': 15
};
let getPrice = (id) => stuffToSell[id];
console.log(getPrice('Coffee Maker'));

How to filter deeply stacked data inside an object(and edit\delete it afterwards)?

I have a problem here, and I can't find out how to solve it. I have an object with many levels. There is arrays with objects inside my object, and they have their arrays with objects too. Let me show you somekind of example here:
{
sections: [
{
currency_sections: [
{
positions: [
{
id: 131,
quantity: 24
},
{
id: 133,
quantity: 1
}
],
key: value,
key: value
},
{
positions: [
{
id: 136,
quantity: 2
},
{
id: 137,
quantity: 3
}
],
key: value,
key: value
}
],
key: value,
key: value
}
],
key: value,
key: value
}
I build my data via handlebars template. Which is not really important. But on my page I can change, let's say, quantity of the position. When I do that I have only id of the position I changed and new quantity.
So basically I need to filter my object to find one object in positions arrays that matches via id key and change quantity there.
Also I can delete whole position, and in that case I need to find position object with id needed and delete whole object.
The thing I can't understand is how I can filter all my data at once. And how can I manipulate unnamed object if I will find it.
And let's say I filtered it somehow. Can I return full path to that object for later use? In example - sections[0].currency_sections[1].positions[0] ? Because if I can do that than deleting and editing should be simple enough.
At this point I don't really have the time to redo everything on something more suitable like angular or ember. Although I have underscore and jquery.
Just wanted to update my question. At the end I just created a method that builds index of my elements.
function _createItemsIndex(data) {
if (!$.isEmptyObject(data)) {
$.each(data.sections, function (sectionIndex, section) {
$.each(section.currency_sections, function (curSecIndex, curSec) {
$.each(curSec.positions, function (positionIndex, position) {
_items.push({
id: position.id,
quantity: position.quantity,
price: parseFloat(position.price) || 0,
index: [sectionIndex, curSecIndex, positionIndex]
});
});
});
});
}
}
Thank you levi for your comments

Clean way of extracting object member values from an array of objects into their own array in JS [duplicate]

This question already has answers here:
From an array of objects, extract value of a property as array
(24 answers)
Closed 8 years ago.
Wonder if there is a cleaner way of doing this then just iterating over every single object, and incrementally rebuilding the array (in Javascript).
var myArray = [{id:10,name:'bob'},{id:30,name:'mike'},{id:40,name:'jay'},{id:50,name:'chris'},{id:60,name:'snake'}];
Indented array output --> [10,30,40,50,60]
map is an higher-order function that applies a function to every member of an array, returning the resulting array.
var myArray = [{
id: 10,
name: 'bob'
}, {
id: 30,
name: 'mike'
}, {
id: 40,
name: 'jay'
}, {
id: 50,
name: 'chris'
}, {
id: 60,
name: 'snake'
}];
myArray.map(function (obj) {
return obj.id;
}); // [10, 30, 40, 50, 60]
Note that this method is absent from IE before version 9, but you can use a polyfill instead if you need to support those browsers.
If you already reference jQuery, $.map offers the same functionality. I suppose underscore.js and the likes also offer an alternative.

Categories

Resources