Arrange objects by property with specific order using javascript - javascript

Is there a way that I could arrange an array of objects according to a certain property whose order is based on an external array (not just alphabetically, numerically, etc.)?
For example, let's say I have a temporary array:
var tempArray = ["b", "a", "d", "c"];
and an array of objects:
var objectArray = [
{ name: "John",
section: "a" },
{ name: "Joe",
section: "b" },
{ name: "Mike",
section: "c" },
{ name: "Mark",
section: "d"}
];
Can I rearrange objectArray so that the object order would follow the contents of tempArray hence returning objectArray as:
objectArray = [
{ name: "Joe",
section: "b" },
{ name: "John",
section: "a" },
{ name: "Mark",
section: "d" },
{ name: "Mike",
section: "c"}
]; // desired output
Any help is very much appreciated.

something like this:
var sorted = objectArray.sort(function(a, b){
return tempArray.indexOf(a.section)-tempArray.indexOf(b.section)
});

You can do that with Array#sort and Array#indexOf. Array#sort sorts arrays, and you can give it a function to call that accepts two arguments, which are two entries to compare to determine which should be before the other. Array#indexOf tells you the index of an entry in the array. So if you use Array#sort on objectArray, and within your callback use Array#indexOf on tempArray to look up the indexes of each object's section property, then compare the indexes (or probably just subtract the second object's index from the first).

Related

How to insert object via push method in javascript?

I cannot add an object via push method to javascript, my code is:
arrObj = [
{
name: "Krunal",
age: 26,
},
{
name: "Ankit",
age: 24,
},
];
function onAdd() {
return CART.push(arrObj);
}
What is the reason ?
if CART is an array, you should use .concat() instead
const newArray = CART.concat(arrObj)
as arr1.concat(arr2) will concat two arrays and return the result
whereas arr1.push(arr2) will result in an array within an array

Is it correct to use .reduce and filter in 1 million json array in node js?

Is it correct to use .reduce and .filter in 1 million json array in node js? I am using JSONStream to parse it. However I need to find the duplicate and unique records and have to do some massage on every records and also have to comparisons between two json array of 1 millions.
What is the best way to approach this? Performance is not a constraint its a background job only. Planning to deploy this job aws ECS using scheduled task.
I am planning to do something like this below
var values = [
{ name: "a", age: 15 },
{ name: "a", age: 17 },
{ name: "a", age: 17 },
{ name: "b", age: 18 },
{ name: "c", age: 18 },
{ name: "d", age: 18 },
{ name: "c", age: 18 },
];
const lookup = values.reduce((a, e) => {
a[e.name] = ++a[e.name] || 0;
return a;
}, {});
console.log("Name count",lookup)
var unique =[];
var dup = values.filter(e => {
if(lookup[e.name]){
return lookup[e.name];
}else {
unique.push(e)
}
});
console.log("Unique:",unique);
console.log("Duplicate", dup)
If you want to know whether this is going to work with a million record array, then you will just have to run it on your system and in your environment to see. That isn't something one can just look at the code and "know". You have to experiment.
I'd have to say that I start out thinking that a million record set of data is probably best managed in a database. If you put all these in a database, then you could structure how you put the data into the database to make it easier to query for all the records with a given name or age or all the records that have a unique name or a non-unique name. This is what databases are built for.
I can see one way that might speed things up a bit. You can build lookup, unique and dup with fewer name lookups. If, while you are building the lookup data structure, you also just keep track of all the items with that particular name, then you can just see which items end up with only one item for a name. So, rather than iterate through all the data and lookup every name, you can just iterate through the lookup data structure and see which names have a cnt of 1 or greater than 1.
I also personally like using a Map object for the lookup since that's what it is built for, but since your keys are strings, your object will probably work just fine too. Anyway, here's a slightly tweaked version:
var values = [
{ name: "a", age: 15 },
{ name: "a", age: 17 },
{ name: "a", age: 17 },
{ name: "b", age: 18 },
{ name: "c", age: 18 },
{ name: "d", age: 18 },
{ name: "c", age: 18 },
];
const lookup = new Map();
const unique = [];
const dup = [];
for (let item of values) {
let array = lookup.get(item.name);
if (!array) {
// if we don't have this name yet, add it to the Map as a one element array
lookup.set(item.name, [item]);
} else {
// otherwise, just push this item into the array
array.push(item);
}
}
// To find unique and dup, we can just iterate the Map and
// look at the length of each array
for (let [name, array] of lookup) {
if (array.length === 1) {
unique.push(array[0]);
} else {
dup.push(...array);
}
}
console.log("Name count", lookup);
console.log("Unique:", unique);
console.log("Duplicate", dup);
The values data structure is not the most efficient way to store a million records that all have the same two properties. It's possible that the interpreter will recognize the internal repetition and optimize it for you, but it could probably be stored more efficiently as:
const values = [
[ "a", 15 ],
[ "a", 17 ],
[ "a", 17 ],
[ "b", 18 ],
[ "c", 18 ],
[ "d", 18 ],
[ "c", 18 ],
];
Or, even just:
const values = [
"a", 15,
"a", 17,
"a", 17,
"b", 18,
"c", 18,
"d", 18,
"c", 18,
];
where the code had some pre-built knowledge for how to get each individual item. You could consider optimizations like this if the memory usage was too high.

Object Values sorting with umulate order

I have been trying to sort the json response object array in specific order like if the object contains Umlaute words/characters
object {
item: 1,
users: [
{name: "A", age: "23"},
{name: "B", age: "24"},
{name: "Ä", age: "27"}
]
}
Expected name sorting is A, Ä and B.
when trying to sort with localecompare().
object.sort(function (a, b) { return a.localeCompare(b); });
Getting the error like object.sort is not a function. Is there anyway to sort the object array.
You need to take the property of the object for sorting.
var object = { item: 1, users: [{ name: "A", age: "23" }, { name: "B", age: "24" }, { name: "Ä", age: "27" }] };
object.users.sort(function (a, b) { return a.name.localeCompare(b.name); });
console.log(object);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You must apply the sort() function to the array, not the outer object. Objects don't have that method and in the general case key order is not guaranteed, anyways. For "ordered" data always use arrays, not objects!
This is an example that uses the o.users array. The output n is also an array.
NOTE: never abuse reserved keywords as variable names. You use object as a variable name, it is strongly recommended to not do so! I've replaced it with o. Albeit object is not a reserved keyword, Object (with capital O) is. And the two are easily confused.
var o = {
"item": 1,
"users": [
{ "name": "A", "age": "23" },
{ "name": "B", "age": "24" },
{ "name": "Ä", "age": "27" }
]
};
var n = o.users.sort((a, b) => a.name.localeCompare(b.name, "de"));
console.log(n);

How to group array elements by arbitrary set of keys?

Having an array of objects I would like to sum the values by combining different set of keys. To be more specific, having an array of objects, describing the meal (0 - Breakfast, 1 - Snack...), I would like to make two different sums:
Sum nutritional values (quantity) for each meal
sum nutritional values (quantity) for whole day
The object array example is the following:
var arrayIngredients = [{mealNumber: 4, name: "Sugars, total", quantity: 1.4300000000000002}, {mealNumber: 4, name: "Magnesium, Mg", quantity: 14.950000000000001}, {mealNumber: 3, name: "Vitamin A, IU", quantity: 27.9}]
Does anyone know what is the most efficient way to sum the values for a given key (name) or multiple keys (mealNumber, name)?
You need to use Array.prototype.reduce (no need of third-party libraries).
Run the following code snippet for a detailed sample:
var arrayIngredients = [{
mealNumber: 4,
name: "Sugars, total",
quantity: 1.4300000000000002
}, {
mealNumber: 4,
name: "Magnesium, Mg",
quantity: 14.950000000000001
}, {
mealNumber: 3,
name: "Vitamin A, IU",
quantity: 27.9
}];
var dayTotals = arrayIngredients.reduce(function(result, next) {
if (!result.hasOwnProperty(next.name))
result[next.name] = {
totalQuantity: 0
};
result[next.name].totalQuantity += next.quantity;
return result;
}, {}); // this empty object is injected as "result" argument
// in the Array.prototype.reduce callback #1 parameter
document.getElementById("result").textContent = JSON.stringify(dayTotals);
<div id="result"></div>

Using lodash to filter the elements of an array with another

Lets say I have the two following arrays
[{
name: "one"
},
{
name: "two" //need an array containing this
}
];
[{
name: "one"
}];
How would I filter the first array to contain only the elements NOT listed in the second using lodash?
Try this
var second = [{name: "one"}, {name: "two"}];
var first = [{name: "one"}];
first = _.pluck(first, 'name'); // get all names - ['one']
second = _.filter(second, function (el) {
return _.indexOf(first, el.name) === -1; // search every name in first array
});
Example

Categories

Resources