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']);
Related
I have two arrays array1 and array 2.Array1 have values with a key name "discount_price" and array2 have values with key name "regular_price".
eg:
discount_price_array,
regular_price_array
When i merge them using array merge i get a single array with combined values. i.e if array1 has 10 elements and array2 has 10 elements it merges into an array with 20 elements. merged_array.
what i want is instead an array with eg:
array{"discount_price":10,"regular_price":2},
array{"discount_price":4,"regular_price":3},
How can i achieve this ?
$(values).each(function(key, value) {
//console.log(value);
if( value.discount_price !==undefined){
discount_price_array.push({ discount_price: value.discount_price })
}
});
$(values).each(function(key, value) {
//console.log(value);
if( value.regular_price !==undefined){
regular_price_array.push({ regular_price: value.regular_price })
}
});
var finalarray =$.merge(discount_price_array,regular_price_array
)
Using map and 'destructuring (...)'
map: lets to iterate over an array and return the same length new array, where you decide what will be returned in every iteration.
(...) spread , allows you to spread the (outer properties) properties in a new object or array, you are basically assigning all object properties to new object, since you are spreading two object in the same new object, they are being merged.
// if both of them have the same length
let arr1 = [{'property1': 10 }, {'property1': 10 },];
let arr2 = [{'property2': 20 }, {'property2': 20 },];
let result = arr1.map((object, index)=> ({...object, ...arr2[index] }));
console.log(result);
simple map only
// if you want to pick which property to assign
let arr1 = [{'property1': 10 }, {'property1': 10 }];
let arr2 = [{'property2': 20 }, {'property2': 20 }];
let result = arr1.map((object, index)=> {
object['property2'] = arr2[index]['property2'];
return object;
});
console.log(result);
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);
First of all i check a lot of post, like this:
Finding matches between multiple JavaScript Arrays
How to merge two arrays in Javascript and de-duplicate items
Unique values in an array
All these works fine but only with arrays that contain integers or strings, i need that works for whatever you want.
i have two arrays, and want to storage in a new array the unique elements, and in other array the common elements.
These elements could be; variables, arrays, strings, hash (objects) functions, integers, float numbers or boolean
And probably never gonna be a duplicate value inside of the arrays.
Would be awesome with plain JS
And i don't care about IE (but would be nice for others i guess), so if there is a new ES6 way, i gonna love it , i care more about performance :)
// Some values that gonna be inside the array1 & array2
function random(){};
var a = 5,
b = {};
// The Arrays
var array1 = [0,1,2,3, "HeLLo", "hello", 55.32, 55.550, {key: "value", keyWithArray: [1,2,3]}, random, a, b];
var array2 = [2,3, "hello", "Hello", 55.32, 55.551, {key: "value", keyWithArray: [1,2,3]}, b];
// The Unique Array should be all the elements that array1 have and array2 haven't
var uniqueArray = [0, 1, "HeLLo", 55.550, random, a];
// The commonArray should the common elements in both arrays (array1 and array2)
var commonArray = [2,3, "hello", 55.32, {key: "value", keyWithArray: [1,2,3]}, b]
// I try something like this but doesn't work
var uniqueArray = array1.filter(function(val) { return array2.indexOf(val) == -1; });
console.log(uniqueArray);
From what I understood you basically want to perform some set operations on your two arrays. My suggestion is to first build a more appropriate data structure from your two arrays, because to do something like get the intersection of both you would have to do an O(n²) algorithm.
Something like this should do it:
// convert a plain array that has values of mixed types to and object
// where the keys are the values in plain form in case of strings, scalars or functions, or serialized objects in
// case of objects and arrays, and where the values are the unaltered values of the array.
var _toObject = function(arr) {
var obj = {};
for (var i=0 ; i<arr.length ; i++) {
var el = arr[i];
var type = typeof el;
if (type !== 'object') { // scalars, strings and functions can be used as keys to an array
obj[el] = el;
}
else { // objects and arrays have to be serialized in order to be used as keys
obj[JSON.stringify(el)] = el;
}
};
return obj;
};
var objArray1 = _toObject(array1);
var objArray2 = _toObject(array2);
var uniqueArray = [];
var commonArray = [];
for (var i in objArray1) {
if (i in objArray2) {
commonArray.push(objArray1[i]); // push the common elements
delete objArray2[i]; // delete so in the end objArray2 will only have unique elements
}
else {
uniqueArray.push(objArray1[i]); // push unique element from objArray1
}
}
for (var i in objArray2) { // now objArray2 has only unique values, just append then to uniqueArray
uniqueArray.push(objArray2[i])
}
console.log('Unique array', uniqueArray);
console.log('Common array', commonArray);
this should give you the desired result:
bash-4.2$ node test.js
Unique array [ 0, 1, 5, 'HeLLo', 55.55, [Function: random], 'Hello', 55.551 ]
Common array [ 2, 3, 'hello', 55.32, { key: 'value', keyWithArray: [1, 2, 3 ] }, {}]
I have a array of objects (arr), each object has 3 properties (Department, Categories, ProductTypes), the values for these properties are a mixture of upper and lower case. I have created a duplicate array of arr and named it arr2. i needed to do a comparison between arr and a search filter (which is already lowercased) so it returns an array of objects back with the matching criteria and assign to arr using:
arr=_.where(arr2,filter);
so I’m thinking to iterate through arr2 and lowercase everything in here, as follows:
_.each( arr2, function(item){ //loop around each item in arr2
_.each( item, function(properties){ //loop around each property in item
properties=properties.toLowerCase();
console.log("Item: ",item,"ID: ",properties);
});
});
however i get the following output in chrome:
Default1.html:109 Item: Object {Departments: "Dep1", Categories: "Cat1", ProductTypes: "Prod1"} ID: dep1
Default1.html:109 Item: Object {Departments: "Dep1", Categories: "Cat1", ProductTypes: "Prod1"} ID: cat1
Default1.html:109 Item: Object {Departments: "Dep1", Categories: "Cat1", ProductTypes: "Prod1"} ID: prod1
How can I change the “Dep1/Cat1/Prod1” values to lowercase?
The reason is the when you use for each or for in loops, you get temp variables which are copies of the original and changes will apply only to the copy.
Here is working code:
arr2 = [{ObjectCategories: "Cat1", Departments: "Dep1", ProductTypes: "Prod1"}]
for (var i =0 ; i<arr2.length; i++){
for (var key in arr2[i]){
if (key === undefined || arr2[i][key] === undefined) {
continue;
}
console.log(key)
console.log(arr2[i][key])
arr2[i][key] = arr2[i][key].toLowerCase();
};
};
console.log(arr2[0])
For the sake of comparing the following code will not work:
arr2 = [{ObjectCategories: "Cat1", Departments: "Dep1", ProductTypes: "Prod1"}]
for (var item in arr2){
for (var key in item){
if (key === undefined || item[key] === undefined) {
continue;
}
console.log(key)
console.log(item[key])
item[key] = item[key].toLowerCase();
};
};
console.log(arr2[0])
You maybe find this interesting.
With some experimenting I managed to solve this, my final code snippet:
var arr2 = [];
_.each( arr, function(item){ //loop around each item in arr
_.each( item, function(properties, id){ //loop around each property in item
if (filter[id] == (item[id].toLowerCase())) {
arr2.push( item );
}
});
});
Basically arr2 is declared empty initially, I iterate through arr via underscore for each item object, then iterate though each of the properties within the item object. I can then check if the search filter variable (which is already lowercase) equals the item's property value in lowercase, if so then add item object to arr2 object array. Simple!
There might be a more shorter function available in underscore to tidy this up even more.
how can I sort object properties by name using another array as refer?
var json = '{"b":90,"c":42, "a":34}';
var obj = JSON.parse(json);
var sorting = ["a","b","c"];
I would like to have obj properties ordered just like sorting array
Thank you
Bye
var sorting = Object.keys(obj).sort();
Javascript objects are not ordered. So, you cannot actually sort them.
Why not just iterating over the array, and then access obj properties ?
for ( var i = 0; i < sorting.length; ++i ) {
var current = obj[ sorting[ i ] ];
// other stuff here...
}
If you don't intent to iterate over the obj, please explain your actual needs.
Convert Object to Array
var jsonArray = [];
$.each(myObj, function(i,n) {
jsonArray.push(n);
});
Sort Array
var jsonArraySort = jsonArray.sort();
Convert Array to Object
var jsonSort = {};
for(var i = 0; i < jsonArraySort.length; i++) {
jsonSort[i] = jsonArraySort[i];
}
You could try something like:
var sorted = []
for (i = 0; i < sorting.length; i++) {
if (json.hasOwnProperty(sorting[i])) {
sorted.push(json[sorting[i]);
}
}
/* sorted will equal [34, 90, 42] */
You cannot order the keys of an object, as per definition,
An ECMAScript object is an unordered collection of propertiesES3 Specs
The mechanics and order of enumerating the properties (step 6.a in the first algorithm, step 7.a in the second) is not specified.
Properties of the object being enumerated may be deleted during enumeration. If a property that has not yet been visited during enumeration is deleted, then it will not be visited. If new properties are added to the object being enumerated during enumeration, the newly added properties are not guaranteed to be visited in the active enumeration. A property name must not be visited more than once in any enumeration.ES5 Specs
If you want to a sorted array consisting of your objects keys, you can use [Object.keys][4], To get an array of them, which you can then sort.
var obj = {b:90,c:42, a:34}
console.log (
Object.keys (obj).sort ()
) // ["a","b","c"]
If you are interested in a sorted array, containing both, keys and values, you could do the following.
var obj = {b: 90, c: 42, a: 34},
srt = Object.keys(obj).sort().map(function (prop) {
return {
key: prop,
value: obj[prop]
}
});
console.log(srt) //[{"key":"a","value":34},{"key":"b","value":90},{"key":"c","value":42}]