I was trying one simple piece of code in which an array of objects are present and each object is having another array of products(with duplicate values).
I wanted to combine all the products array together without any duplicates.
Already reached half of iteration process but not able to remove duplicates, is there any way to iterate the values (as it is itself having key value as object 1 and its data..)
please suggest any other optimized way if possible. I'm new to JavaScript so pardon any silly mistakes made
Thanks in advance.
You can do it using concat, Set and Array.from:
const object1 = { products: ['1', '2', '3'] }
const object2 = { products: ['1', '2', '3', '4'] }
const object3 = { products: ['5'] }
// Merge all the products in one Array
const products = object1.products
.concat(object2.products)
.concat(object3.products);
// Create a Set, with the unique products
const set = new Set(products);
// Convert the Set to an Array
const uniqueProducts = Array.from(set);
console.log(uniqueProducts)
To remove duplicates you can use Set, it keeps all items unique, then you can cast it to Array.
Array.from(new Set(array))
there are many ways to achieve this:
you can use filter to remove duplicate elements:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
by reading in value, its index and array in filter function
a quick search link: https://codeburst.io/javascript-array-distinct-5edc93501dc4
you can always write a method for merge which would be good in terms of error handling, corner case checks, so that above action dont result into error,
example:
function MergeUniqueProductFromDictToArry(fromDict, productKey, toArray) {
//check if for the array in which we need to merge
if(!toArray) {
toArray = [];
}
//check for validity
if(!fromDict || !productKey || !fromDict[productKey] || fromDict[productKey].length == 0) {
return toArray;
}
for(var ix in fromDict[productKey]) {
//check if product already exist
if(toArray.indexOf(fromDict[productKey][ix]) === -1) {
toArray.push(fromDict[productKey][ix]);
}
}
return toArray;
}
var object1 = {products: ["p1", "p2", "p1"]};
var object2 = {products: ["p3", "p2"]};
var object3 = {products: ["p4", "p2"]};
var uniqueProducts = MergeUniqueProductFromDictToArry(object1, "products", null);
uniqueProducts = MergeUniqueProductFromDictToArry(object2, "products", uniqueProducts);
uniqueProducts = MergeUniqueProductFromDictToArry(object3, "products", uniqueProducts);
console.log(uniqueProducts);
Related
I have duplicate values looks like as shown in below figure
I have used below code but its only giving the names like as ashare1 guideline2and i am looking for id as well.
please find the below code currently i have used
const optionMap0 = [
...new Set(libraryEquipment.map(e => e.equipmentSource.name)),
{
id: '1d037be564c548eebe71db4e45e26cf7',
name: 'None',
},
];
Could any one please suggest any idea on how to get distinct values from the above array of objects.
many thanks in advance
You can convert it to an object, with the key as the name, and the value as the object itself, and then use Object.values() to get the objects.
const obj = {};
libraryEquipment.forEach(e => obj[e.equipmentSource.name] = e.equipmentSource);
const optionMap0 = Object.values(obj);
Unlike set, if you have more than one object with the same name, it will keep the last one. You can check before adding the object so it will use the first object with the same name, like so:
const obj = {};
libraryEquipment.forEach(e => {
if (!obj[e.equipmentSource.name])
obj[e.equipmentSource.name] = e.equipmentSource'
});
const optionMap0 = Object.values(obj);
I have looked at this question in stack overflow about objects guaranteeing order.
Does JavaScript Guarantee Object Property Order?
some says they guarantee, some says they don't, depending on situations. Meantime I've encountered following problem.
I have an array of objects, similar to below:
const arrayObject = [
{id:'a123', bar:'hello'},
{id:'a321', bar: 'foo'} ];
now I wish to turn this arrayObject into object of object, with structure as follows with the same order as the array:
const object = {
'a123': {id:'a123', bar:'hello'},
'a321': {id:'a321', bar: 'foo'},
}
basically using the id of each item in the array as the key of the object. Below is the code I used to try to achieve it:
let newObj = {};
arrayObject.forEach(data=>{
const temp = {
[data.id]:{
id: data.id,
bar: data.bar
},
};
newObj={...newObj, ...temp};
})
I do get the correct structure, however the order is not the same as the order of arrayObject, i.e. it returns:
const object = {
'a321': {id:'a321', bar: 'foo'},
'a123': {id:'a123', bar:'hello'},
}
I've tried with more items in the array, and I get same result. It does not guarantee the order.
Is there something wrong with my code, or is it simply not guaranteeing the order?
What do I have to do to make the object be the same order as the array?
Preserve the order by including ordering information in the (unordered) object. Anytime later, when you need to recover the original order, use the saved ordering information...
const arrayObject = [{
id: 'a123',
bar: 'hello'
},
{
id: 'a321',
bar: 'foo'
}
];
let object = {}
arrayObject.forEach((e, i) => {
object[e.id] = { ...e, orderWith: i } // the index will tell us how to sort later
})
// later on
let sorted = Object.values(object).sort((a, b) => a.orderWith - b.orderWith)
console.log(sorted)
I think what you're looking for is a Map() object. See here -> Map and Set
const arrayObject = [
{id:'a123', bar:'hello'},
{id:'a321', bar: 'foo'},
{id:'a234', bar: 'more'},
{id:'a735', bar: 'words'},
{id:'a167', bar: 'added'},
{id:'a857', bar: 'now'},
];
var newObj = new Map();
for (var i=0; i<arrayObject.length; i++) {
const temp = {
id: arrayObject[i].id,
bar: arrayObject[i].bar
};
newObj.set(arrayObject[i].id, temp);
}
var jsonText = JSON.stringify(Array.from(newObj.entries()));
console.log(jsonText);
// To get at the elements, use .get()
console.log(newObj.get("a321").bar);
A simpler bit of code would be like this (use a for loop instead of forEach:
let newObj = {};
for (const data of arrayObject) {
newObj[data.id] = data;
}
This might get you what you want because it will guarantee that the order the object is built matches the order in the array. Using forEach causes multiple functions to be called in whatever order they run, which might be out of order. But realize that even using the for-loop does not guarantee the order will always match. An Array will guarantee the order, but the Object made this way does not. Even if the above code does give you the desired order, it might not in the future. Use an Array if you need to preserve order.
In the following function I push and object to the accountsToDelete array, I need to then remove the matching object from the accountsToAdd array. I am guessing I would have to use a combination of IndexOf, Filter, Reduce but I am still a little rough in understanding how to accomplish this. This is the current function:
accountDelete(id, name) {
const accountsToAdd = this.userForm.value.accountsToAdd;
const accountsToDelete = this.userForm.value.accountsToDelete;
this.userForm.value.accountsToDelete.push(
{
id: id,
name: name
}
);
}
You can simply use the filter function. By this you can say, that in the accountToAdd all entries should be filtered, which id fits the to deleted account.
An example:
// Initialize both lists.
let accountsToAdd = []
let accountsToDelete = []
// Preparation by adding a account to the first list.
const account = { id: 1, name: 'Max' }
accountsToAdd.push(account)
// Mark account to be removed.
accountsToDelete.push(account)
accountsToAdd = accountsToAdd.filter(acc => acc.id !== account.id)
// Verify result.
console.log(accountsToAdd)
console.log(accountsToDelete)
Note:
Your both lists are defined as constant. By this you can't use the reassignment.
So the issues that I am currently having is a string manipulation logic issue. My goal is to store the names of JSON objects in a string array. So it will be easier to access the data later on. But the current issue that I am running into is that the output is nothing that I want or understand of how it is getting it. Currently I am looking for the quotes between the object names and returning it to a string using str.substring, and storing it in an index of newArr. The output equals in 4th code snippet. I have also tried putting an underscore before and after the object name in the JSON object, then searching for the underscore. From my testing this will only work with the first name, which will return "foo" in index 0, while the rest of the indexes equal to '"_'. I know there is something wrong with my logic in the function, but I can not pinpoint what it is. Any help would be appreciated
This is the function that is being ran.
exports.jsonObjectToArray = function (objectToTurn){
var oldArr = JSON.stringify(objectToTurn).split(","),
firstIndex,
secondIndex,
newArr = [];
for(let i = 0; i < oldArr.length; i ++){
firstIndex = oldArr[i].indexOf("\"");
secondIndex = oldArr[i].indexOf(firstIndex, "\"");
newArr[i] = oldArr[i].substring(firstIndex, secondIndex);
}
return newArr;
}
When the function is ran oldArr will equal to this value.
[ '{"foo":"',
'"bar":"0"',
'"Mar":"0"',
'"Car":"0"}'
]
And my goal is to return this. Which will be stored in newArr.
[
"foo",
"bar",
"Mar",
"Car"
]
But after the function runs this is what I get returned.
[
'{"',
'bar":"0',
'Mar":"0',
'Car":"0'
]
To get the keys from an object, simply use Object.keys().
Quick example:
var obj = {
foo: '1',
bar: '2',
car: '3'
};
console.log(Object.keys(obj)); // ==> (3) ["foo", "bar", "car"]
let arr = [ '{"foo":"',
'"bar":"0"',
'"Mar":"0"',
'"Car":"0"}'
]
let arr1 = arr.map(el => el.split('"')[1])
I have an array with 1000 elements in it. However, the array follows a sequence - every ten elements.e.g. [fruit,vegetables,sugars,bread,fruit,vegetables,sugars ....].
I would need to extract every fruit, vegetable and so on into different arrays, however there are 10 classes of them and I need to make ten different arrays out of this one.
What would be the most reliable approach to this problem?
Work is on JavaScript
You could take an array with references to the wanted arrays and as index for the array for pusing the remainder value of the actual index and the length of the temporary array.
var array = ['fruit', 'vegetables', 'sugars', 'bread', 'fruit', 'vegetables', 'sugars', 'bread'],
fruits = [], // final arrays
vegetables = [], //
sugars = [], //
breads = [], //
temp = [fruits, vegetables, sugars, breads],
len = temp.length;
array.forEach((v, i) => temp[i % len].push(v));
console.log(fruits);
console.log(vegetables);
console.log(sugars);
console.log(breads);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Not super elegant but it will do the job..
var a =
['bread_1','fruit_1','vegetable_1','sugars_1',
'bread_2','fruit_2','vegetable_2','sugars_2',
'bread_3','fruit_3','vegetable_3','sugars_3'];
var i=0;
a = a.reduce(function(ac, va, id, ar){
if(i==ac.length) i=0;
ac[i].push(va);
i++;
return ac;
}, [[],[],[],[]]);
console.log(a);
I suggest (since the pattern may vary) to create an array with categories and what elements those categories include, thus creating an object with keys identifying your categories.
The variables are not 'declared' outside the object but you can access the object keys the same way you'd have different variables:
// Simple old-style catalog as reference for your elements array.
var Categories = {
'fruits': ['orange', 'apple', 'all other fruits…'],
'vegetables': ['ginger', 'broccoli', 'all other vegetables…'],
'bread': ['pizza', 'panini', 'all other breads…'],
'sugars': ['soda', 'sugar1', '90_percent_of_products_are_sugar', 'all other sugars…']
};
// Your actual elements array.
var ElementsArray = [
'orange',
'broccoli',
'pizza',
'sugar1',
'apple',
'ginger',
'panini',
'soda'
];
// Your organized-by-category variable, declare as object so you can easily access as Array or Object (keys are the variable arrays).
var OrderedElementsArray = {};
for (element in ElementsArray)
{
for (category in Categories)
{
// Check if the key is not an array an initialize it for later use of push().
if (typeof OrderedElementsArray[category] != 'object')
{
OrderedElementsArray[category] = [];
}
// indexOf() returns -1 if no element matches an index, thus the expression `>= 0`.
if (Categories[category].indexOf(ElementsArray[element]) >= 0)
{
OrderedElementsArray[category].push(ElementsArray[element]);
}
}
}
// Here you can access your object variables with dot notation. All your categories will be accessible either way.
console.log(OrderedElementsArray.fruits);
console.log(OrderedElementsArray.vegetables);
console.log(OrderedElementsArray.bread);
console.log(OrderedElementsArray.sugars);
// Here you can access your object variables with key notation. All your categories will be accessible either way.
console.log(OrderedElementsArray['fruits']);
console.log(OrderedElementsArray['vegetables']);
console.log(OrderedElementsArray['bread']);
console.log(OrderedElementsArray['sugars']);