I have the following JavaScript array:
var allItems = ['BBL_NO1', 'BBL_NO2', 'BBL_N03', 'BBL_NO4', 'AAL_NO1', 'AAL_NO2', 'MML_NO1', 'MML_NO2'];
Now I want to sort the array in this format, to put the values in a dropdown:
var sorted = { 'BBL': ['BBL_NO1', 'BBL_NO2', 'BBL_N03', 'BBL_NO4'],
'AAL': ['AAL_NO1', 'AAL_NO2'],
'MML': ['MML_NO1', 'MML_NO2']};
Does anyone know how I can do that?
You can do it using Array.prototype.reduce() function.
Example:
var allItems = ['BBL_NO1', 'BBL_NO2', 'BBL_N03', 'BBL_NO4', 'AAL_NO1', 'AAL_NO2', 'MML_NO1', 'MML_NO2'];
var sorted = allItems.reduce(function (acc, item) {
var mainPart = item.split('_')[0];
if (!acc.hasOwnProperty(mainPart)) {
acc[mainPart] = [];
}
acc[mainPart].push(item);
return acc;
}, {});
console.log(sorted);
Related
It's a complicated scenario but will try to explain as much as possible. I have one object or arrays and one array. Now i have to compare selectedmodel values with mappedmodels, if the value(Case insensitive) matches with that object then fetch all the values of it and push it into selected model and combine both. Hope the example will clear what i am trying to achive.
var mappedModels = { 'CC605': ['cc605', 'CC605', 'cC605'], 'TC75X': ['TC75X'] };
var selectedModels = ['CC605', 'tc76'];
var desiredOutput = ["CC605", "tc76", "cc605", "cC605"];
I already wrote a solution to achieve it but i need a better code in terms of performance. Here is the solution:
function combineModelCases(selectedModels) {
const modelCases = [];
selectedModels.forEach(elm => {
const existingModels = mappedModels[elm.toUpperCase()];
if (existingModels) {
for (const key of existingModels) {
if (elm.toUpperCase() !== key) {
modelCases.push(key);
}
}
}
});
return selectedModels.concat(modelCases);
}
Here is Fiddle
I am using typescript and underscore js for your references. Any help would be very helpful.
You could use flatMap to get a flattened array of values for each key in selectedModels. Then, create a Set to get a unique collection models. Use Array.from() to convert the set to an array.
const mappedModels = { 'CC605': ['cc605', 'CC605', 'cC605'], 'TC75X': ['TC75X'] },
selectedModels = ['CC605', 'tc76'];
const models = selectedModels.flatMap(m => mappedModels[m] || []),
unique = Array.from(new Set([...selectedModels, ...models]));
console.log(unique)
you can do the following, :
var mappedModels = { 'CC605': ['cc605', 'CC605', 'cC605'], 'TC75X': ['TC75X'] };
var selectedModels = ['CC605', 'tc76'];
var desiredOutput;
function combineModelCases(selectedValue){
if(mappedModels.hasOwnProperty(selectedValue)){
desiredOutput = [... new Set([...mappedModels[selectedValue], ...selectedModels])]
return desiredOutput;
}
}
console.log(combineModelCases('CC605'));
here is the working demo : https://jsfiddle.net/wzo4d6uy/2/:
I have the following object:
Object { WK23: 12.52573059875292, WK22: 122.2625975869411, WK21:
78.48714311048059, WK20: 87.14214810403018, WK26: 78.52625051674245, WK25: 77.64480983891451, WK24: 67.42158281711342, WK2:
78.420343898902, WK3: 77.91344340707354, WK4: 77.29048185059888 }
Is it possible to sort it by keys, from WK1 to WK100 ?
How to do this in JavaScript ?
Thanks in advance,
Try this , you can change order and assign to different object
var unordered={ WK23: 12.52573059875292, WK22: 122.2625975869411, WK21: 78.48714311048059, WK20: 87.14214810403018, WK26: 78.52625051674245, WK25: 77.64480983891451, WK24: 67.42158281711342, WK2: 78.420343898902, WK3: 77.91344340707354, WK4: 77.29048185059888 }
console.log(JSON.stringify(unordered));
const ordered = {};
Object.keys(unordered).sort(function(a,b){
var a=a.split("WK")[1];
var b=b.split("WK")[1];
return a-b
}).forEach(function(key) {
ordered[key] = unordered[key];
});
console.log(JSON.stringify(ordered));
No, you can't. Object keys are not ordered. If you want to sort entries in an Object, you will have to convert it into an Array.
var obj = {"WK23": 12.52573059875292, "WK22": 122.2625975869411};
var result = Object.keys(obj).map(function(key) {
return [key, obj[key]];
});
// the result Array can then be sorted...
// result = [["WK23": 12.52573059875292], ["WK22": 122.2625975869411]]
var sorted = result.sort(function(a,b){
var num_a = parseInt(a[0].replace("WK", ""));
var num_b = parseInt(b[0].replace("WK", ""));
return num_a > num_b;
});
// sorted = [["WK22": 122.2625975869411], ["WK23": 12.52573059875292]]
here you go
const sample = { WK23: 12.52573059875292, WK22: 122.2625975869411, WK21:
78.48714311048059, WK20: 87.14214810403018, WK26: 78.52625051674245, WK25: 77.64480983891451, WK24: 67.42158281711342, WK2:
78.420343898902, WK3: 77.91344340707354, WK4: 77.29048185059888 };
const sorted = Object.keys(sample).sort().map(key => sample[key]);
I have data in following format..
var array = [{"name":"abc","boss":"def","sub":[{"schema":"a","data":1},{"schema":"b","data":0},{"schema":"c","data":0}]},
.
.
.
]
I wish to transform it to the following structure:
[{"name":"abc","boss":"def","a":1,"b":0,"c":0},
.
.
.
]
Based on the answer here.. I tried..
grouped = [];
array.forEach(function (a) {
if (!this[a.name]||!this[a.boss]) {
this[a.name] = { name: a.name, boss:a.boss };
grouped.push(this[a.name]);
}
this[a.name][a.sub.schema] = (this[a.name][a.sub.schema] || 0) + a.sub.data;
}, Object.create(null));
console.log(grouped);
The above gives undefined:NaN as the third property in the result objects..
Any help is sincerely appreciated.
Thanks
You probably want to reduce the sub object to properties of the item.
The following code maps the items in array to a new array, which contains the flattened items:
array = array.map(function(item) {
item = item.sub.reduce(function(x,y) { return x[y.schema] = y.data, x; }, item);
delete item.sub;
return item;
});
Try this simply.
var arr = [];
array.forEach(function(ele){
var obj = {};obj.name=ele.name;
obj.boss=ele.boss;
ele.sub.forEach(function(e){
obj[e.schema] = e.data
});
arr.push(obj)
});
I have an array of objects like this:
var bridges = {"countyCd:15
createdDate:"0001-01-01T00:00:00"
createdUserId:0
createdUserIdZ:null
createdUserName:null
description:"SR 1#.-CENTRAL RR COMP OF IND"
districtId:null
encryptedId1:null
encryptedId2:null
isDirty:false
modelState:null
nbiNumber:10
routeNbr:"1"
routeTypeCd:"SR"
transactionType:null
updatedDate:"0001-01-01T00:00:00"
updatedUserId:0
updatedUserIdZ:null
updatedUserName:null", [...]....}
I have another array like this
[countyCd, nbiNumber]
How can create another array keeping just two properties so it becomes like
bridges = {"countyCd:15
nbiNumber:10"
, [...]....}
Basically, I am looking for a way to create a function that takes a data array and a filter array as parameters and filters the data array based on the filter array.
Any pointers to this will be much appreciated.
One solution would be to map over each record and reduce your filter array into an object containing the target proprties:
var bridges = [{
countyCd:15,
createdDate:"0001-01-01T00:00:00",
createdUserId:0,
createdUserIdZ:null,
createdUserName:null,
description:"SR 1#.-CENTRAL RR COMP OF IND",
districtId:null,
encryptedId1:null,
encryptedId2:null,
isDirty:false,
modelState:null,
nbiNumber:10,
routeNbr:"1",
routeTypeCd:"SR",
transactionType:null,
updatedDate:"0001-01-01T00:00:00",
updatedUserId:0,
updatedUserIdZ:null,
updatedUserName:null
}, {
countyCd:23,
createdDate:"0001-01-01T00:00:00",
createdUserId:0,
createdUserIdZ:null,
createdUserName:null,
description:"SR 1#.-CENTRAL RR COMP OF IND",
districtId:null,
encryptedId1:null,
encryptedId2:null,
isDirty:false,
modelState:null,
nbiNumber:10,
routeNbr:"1",
routeTypeCd:"SR",
transactionType:null,
updatedDate:"0001-01-01T00:00:00",
updatedUserId:0,
updatedUserIdZ:null,
updatedUserName:null
}];
var filters = ['countyCd', 'nbiNumber'];
var transformedRecords = bridges.map(bridge => filters.reduce((p, c) => {
p[c] = bridge[c];
return p;
}, {}));
console.log(transformedRecords);
Say you have an array of bridges, call it bA:
var bA = []; //bridges array
var nbiA = []; // nbia array with countyCd
var newA = []; // new array
bA.forEach(function(element, index, array){
var newEntry = {
'countyCd':element.countyCd,
'nbiNumber':nbiA.find(function(nbi){
return nbi[countyCd] == element.countyCd;
}).nbiNumber
};
newA.push(newEntry);
});
//do whatever you want with the newA array
My data is in the following format..
var data= [['typeName', 'valueName'], ['type1', 'value1'],
['type1', 'value2'],['type2', 'value3'],['type2', 'value4']]
I wish to transform the above data to data as below..
var resultdata=[{'typeName':'type1','valueName':['value1','value2']},
{'typeName':'type2','valueName':['value3','value4']}]
Basically I pick up distinct 'typeName' values and then group 'valueName' values by 'typeName' values.
I would preferably use only knockoutjs, lodash or underscorejs as my soln already uses them but I'm open to other solutions as well..
All help is sincerely appreciated
Thanks
I think this solution using underscore should do the trick:
var result= _.chain(data)
.rest()
.groupBy( value => value[0])
.map( (value,key) => ({ [data[0][0]]: key, [data[0][1]]: _.map(value, val => val[1])}))
.value();
This solution uses rest to skip the first item in the data array (the type descriptors). The array is then grouped by the first value in the array (the type) and the mapping returns the grouping in the required form using es6 object initializer notation.
Given the result as:
var resultdata=[
{'typeName':'type1'},{'valueName':['value1','value2']},
{'typeName':'type2'},{'valueName':['value3','value4']}
]
I'm going to call 'typeName' the category and 'valueName' the items.
Since the original data look like this:
var data= [
['typeName', 'valueName'],
['type1', 'value1'],
['type1', 'value2'],
['type2', 'value3'],
['type2', 'value4']
]
It is clear there is a pattern. The first row of data is what we'll use as labels for category and items. All the remaining data represent the values being used inside category and items.
The first step is to extract the labels:
var categoryLabel = data[0][0];
var itemLabel = data[0][1];
Next, the unique categories will need to be determined, so we'll use reduce to build an array of unique categories:
var categories = data
.filter(function(row, i) { return i > 0 }) // remove the labels
.reduce(function(arrCategories, currRow) {
// Add the current rows' category if it doesn't already exist
var currCategory = currRow[0];
if (arrCategories.indexOf(currCategory) === -1) {
return arrCategories.concat(currCategory);
}
return arrCategories;
}, [])
Now that you have a set of categories, you just need to iterate over each one to find all items that belong to it:
var valuesByCategory = {};
categories.forEach(function(category) {
// find all the data items that match the category
var items = data
.filter(function(row) { return row[0] === category; })
.reduce(function(arrItems, currRow) {
var currItem = currRow[1];
if (arrItems.indexOf(currItem) === -1) {
return arrItems.concat(currItem);
}
return arrItems;
}, []);
valuesByCategory[category] = items;
});
Now that all the data has been parsed out, the only thing left to do is build the resultant array:
var resultdata = [];
// iterate through each of the categories
categories.forEach(function(category) {
// using the category label, output an object with the label and category
var categoryObj = {};
categoryObj[categoryLabel] = category;
resultdata.push(categoryObj);
// Next, create a items object containing all the values
var itemsObj = {};
itemsObj[itemLabel] = valuesByCategory[category];
resultdata.push(itemsObj);
}
and that's it :)
The best part is that you don't need any external libraries. This is all ES2015 javascript!
Here is a lodash version of Gruff Bunnies solution:
var data= [['typeName', 'valueName'], ['type1', 'value1'], ['type1', 'value2'],['type2', 'value3'],['type2', 'value4']]
var names = data[0]
var values = _.tail(data)
console.log(JSON.stringify(
_(values)
.groupBy(0)
.map( (value, key) => ({ [names[0]]: key, [names[1]]: _.map(value, 1)}) )
.value()
))
https://jsfiddle.net/nmf1fdf5/