JavaScript - Arbitrary Sort [duplicate] - javascript

This question already has answers here:
Javascript - sort array based on another array
(26 answers)
Closed 3 years ago.
I have an array like this:
var data = ['High', 'Low', 'Medium'];
This data array is created dynamically. So, it may have all 3 values or only 2 values or 1 value.
Regardless of the values in the array, I would like the array to be sorted in this fashion:
var sortedArray = ['High', 'Medium', 'Low']
I have tried something like this:
var sortedArray = []
for(var 0;i<data.length;i++)
{
if(data[i] = 'High')
{
sortedArray.push('High');
}
else if(data[i] = 'Medium')
{
sortedArray.push('Medium');
}
else if(data[i] = 'Low')
{
sortedArray.push('Low');
}
}
How can we achieve that?

You can start with the complete array already sorted, and filter out the elements that aren't in data.
var data = ['Low', 'High'];
var sortedArray = ['High', 'Medium', 'Low'].filter( el => data.includes( el ) );
console.log( sortedArray );

var data = ['High', 'Low', 'Medium'];
// create a dictionary to map each possible value
var map = {High: 3, Medium: 2, Low: 1, Default:0 };
// then sort
var sorted = data.sort((a,b)=>(map[a]||map.Default)>(map[b]||map.Default)?-1:1);
console.log(sorted);

Related

how to sort and get last value and index in javascript [duplicate]

This question already has answers here:
get key of max value in dictionary nodejs
(2 answers)
Getting key with the highest value from object
(9 answers)
Closed 2 years ago.
i create a let in JavaScript below format
let map={'431':232,'432':123,'433':120}
i want to order the map into following format. order by value.
map={'433':120,'432':123,'431':232}
at last i need to store index and value as numbers.
int1=431 // index as number
int2=232 // values as number
Convert the object to an entries array
Sort it by key (entry[0])
Grab the last entry by index or via Array.prototype.pop()
let map = {'431':232,'432':123,'433':120}
const sorted = Object.entries(map).sort(([ key1 ], [ key2 ]) =>
key2 - key1)
const [ int1, int2 ] = sorted[sorted.length - 1]
console.info(int1, int2)
Use Object.entries, sort them and take the first element (using destructure)
let map = { '431': 232, '432': 123, '433': 120 };
const [[key, value]] = Object.entries(map).sort(([a], [b]) => +a - +b);
console.log(key, value);
it creates your goal object and what you want you can find.
let map={'431':232,'432':123,'433':120}
var keys = [];
var values = [];
for(var k in map) keys.push(parseInt(k));
for(var v in map) values.push(map[v]);
values = values.sort().reverse();
let finalObj=[];
for(i=0;i<keys.length;i++){
let obj = {};
obj[keys[i]] = values[i];
finalObj.push(obj)
}
console.log(finalObj[finalObj.length-1])

Parse data into JavaScript arrays

I have an array data format coming from back-end which looks like:
Array
[{"ckey::"C1","date":"0506","rows":17},
{"ckey::"C1","date":"0706","rows":7},
{"ckey::"C2","date":"0706","rows":13},
{"ckey::"C2","date":"0806","rows":11}]
So for few days C1 data is there and few days C2 data.
Only one day has C1 and C2 data both.
I want to build an array like for C1 and C2
[[17,7,0],[0,13,11]]
First nested array for C1 where third value is 0 because for 0806 date the value was not present.
Second nested array for C2 where first value is 0 because for 0506 date the value was not present.
Please help. I cannot form the array effectively.
I think it would be O(n^3) solution. But please help with the same.
UPDATE
Here was my approach, I could not post the code here but it looks something like this.
I was getting date values in separate array like and I filter for unique days.
angular.forEach(data, function(obj){
if(timeData.indexOf(obj.date) === -1)
timeData.push(obj.date);
});
Then
ckey array _distinctckeyArray also were there containing values ["C1","C2"].
angular.forEach(_distinctckeyArray,function(_ckey){
var _formattedDataArrItem = [];
angular.forEach(timeData,function(_dateTimeString) {
var _tempDataVolume = [];
angular.forEach(_data,function(_dataObj) {
if(_dataObj.date === _dateTimeString) {
if(_dataObj.ckey === _ckey) {
_tempDataVolume.push(_dataObj.rows);
}else {
_tempDataVolume.push(0);
}
}
});
});
You can make an object dates that will have date properties. Initialize the values to 0
You reduce to group the array. Use Object.values to convert the object into an array.
let arr = [{ckey:"C1","date":"0506","rows":17},{ckey:"C1","date":"0706","rows":7},{ckey:"C2","date":"0706","rows":13},{ckey:"C2","date":"0806","rows":11}];
//Make an object with property dates. assign all property to 0 as initial value.
//Expected output:
//{"0506":0,"0706":0,"0806":0}
let dates = arr.reduce((c, v) => Object.assign(c, {[v.date]: 0}), {});
//Loop thru the array using `reduce`.
//This is to group the array to object using the ckey as the key
//After grouping, use `Object.values` to convert the object into array
let result = Object.values(arr.reduce((c, {ckey,date,rows}) => {
c[ckey] = c[ckey] || { ...dates }; //Check if c[ckey] exist. If it does not, "clone" the dates object.
c[ckey][date] = rows; //Overide the initial value 0 to the rows value
return c;
}, {})).map(o => Object.values(o));
console.log(result);
I think this is what you are looking for. Let me know.
let data = [{
'ckey': 'C1',
'date': '0506',
'rows': 17
}, {
'ckey': 'C1',
'date': '0706',
'rows': 7
}, {
'ckey': 'C2',
'date': '0706',
'rows': 13
}, {
'ckey': 'C2',
'date': '0806',
'rows': 11
}]
function nested_arrays(array) {
const result = []
const obj = {
c1: [],
c2: []
}
for (let i = 0; i < array.length; i++) {
if (array[i].ckey === 'C1') {
obj.c1.push(array[i].rows)
}
if (array[i].ckey === 'C2') {
obj.c2.push(array[i].rows)
}
}
obj.c1.push(0) // set last value to 0
obj.c2.unshift(0) // set first value to 0
result.push(obj.c1, obj.c2)
return result
}
let _tempDataVolume = nested_arrays(data)
console.log(_tempDataVolume) //=> [ [ 17, 7, 0 ], [ 0, 13, 11 ] ]
let arr = [{"ckey::"C1","date":"0506","rows":17},
{"ckey::"C1","date":"0706","rows":7},
{"ckey::"C2","date":"0706","rows":13},
{"ckey::"C2","date":"0806","rows":11}]
arr.map(res =>{
let c1arr = [],
let c2arr = [],
if(res.ckey== 'C1'){
c1arr.push(res.rows)
}else{ c2arr.push(res.rows) }
})
let newArrr = []
newArr.push(c1arr);
newArr.push(c2arr);
console.log('arr is',newArr)

How to check in array how much times each word repeats itself and push it to another array [duplicate]

This question already has answers here:
Counting the occurrences / frequency of array elements
(39 answers)
Closed 5 years ago.
Lets say i have an array like this:
let votesArr = [yes,no,yes,no,yes];
and i want to to count how much times every word repeats itself and push to another so the output looks like this:
let votesData = [3,2]; // 3 for three yeses and 2 for two nos.
and i want to to work on many types of arrays like this, lets say an array that has 3 or 4 unique word.
I'm trying for a lot of time already and can't do that.
You could use the power of Map.
var array = ['yes', 'no', 'yes', 'no', 'yes'],
map = new Map,
result;
array.forEach(v => map.set(v, (map.get(v) || 0) + 1));
result = [...map.values()];
console.log(result);
Just returning a plain array of counts will not make sense I guess. It should be more like below. If you don't want this output then just map the values to form an array.
{
"yes": 3,
"no": 2
}
let votesArr = ["yes","no","yes","no","yes"];
const mappedArr = votesArr.reduce((a, b) => {
a[b] = a[b] || 0;
a[b] += 1;
return a;
}, {});
console.log(mappedArr);
You can do this as follows:
let votesArr = ["yes","no","yes","no","yes"];
let countSummary = votesArr.reduce( (count, val) => {
if(!count[val]) { count[val] = 0 }
count[val]++;
return count;
}, {})
console.log(countSummary)// {yes: 3, no: 2}
let countSummmaryArr = Object.keys(countSummary).map(k=>countSummary[k]);
console.log(countSummmaryArr )// [3,2]
The way this works is that the .reduce counts every instance to a map of values, and the .map converts it to an array of the values.
The below does what you need, although I'm sure it could be cleaned up a bit.
var data = ["Unsure", "Yes", "Yes", "No", "Yes", "No", "Maybe", "Unsure"];
var counts = {};
for (var i = 0; i < data.length; i++) {
(counts[data[i]]) ? counts[data[i]]++ : counts[data[i]] = 1;
}
// counts = {Unsure: 2, Yes: 3, No: 2, Maybe: 1}
You can do like this
let votesArr = ['yes', 'no', 'yes', 'no', 'yes'];
// Create an empty object to store array item as key & its
// number of repeat as value
var itemObj = {};
// loop over it and store the value in the object
var m = votesArr.forEach(function(item) {
if (!itemObj[item]) {
itemObj[item] = 1
} else {
itemObj[item] = itemObj[item] + 1
}
});
// Use object.values to retrive the value
console.log(Object.values(itemObj))

How to remove an array from a multidimensional array if it exists in another multidimensional array? [duplicate]

This question already has answers here:
How to compare arrays in JavaScript?
(55 answers)
Closed 8 years ago.
I have two multidimensional arrays and need to remove all the arrays from array A that exist in array B. I've tried it this way with no luck:
var arrayA = [[0,1], [2,0], [0,3], [4,0], [0,5]];
var arrayB = [[0,1], [0,3]];
arrayA = arrayA.filter( function( el ) {
return arrayB.indexOf( el ) < 0;
} );
alert(arrayA);
This works when the elements in arrayA and arrayB are single values and but when they are arrays. Not sure what I am doing wrong?
Assuming the inner arrays are always in the same order to match:
for (var i = 0; i < arrayA.length; i++) {
for (var j = 0; j < arrayB.length; j++) {
if (JSON.stringify(arrayA[i]) == JSON.stringify(arrayB[j])) {
arrayA.splice(i, 1);
break;
}
}
}
Fiddle: http://jsfiddle.net/o2qk7hjd/
Array.prototype.indexOf uses strict equals comparison to check if elements are equal. This wont work for reference types since [] === []; is false. You can either use #tymeJV solution which is O(lenA*lenB) complexity or preindex arrayB making it O(lenA + lenB)
Demo.
function index(arr) {
return arr.reduce(function(acc, item){
return acc[JSON.stringify(item)] = item, acc
}, {});
}
var arrayA = [[0,1], [2,0], [0,3], [4,0], [0,5]];
var arrayB = [[0,1], [0,3]];
var indexB = index(arrayB);
arrayA = arrayA.filter( function( el ) {
return !(JSON.stringify(el) in indexB);
} );
console.log(arrayA);
UPD
If the order of elements inside inner arrays is not quaranteed you can use sort. This will make this task O(lenA*log(lenA) + lenB*log(lenB))
Demo 2.
You can do it like this
var arr = arrayA.map(function(x){ return x + "" }); // convert the array to string
arrayB.forEach(function(e) {
var idx = (arr.indexOf(e + "")); // find the index
arr.splice(idx, 1); // remove it
});
arrayA = arr.map(function(x) { return x.split(","); });

Removing arrays from other arrays [duplicate]

This question already has answers here:
How to get the difference between two arrays in JavaScript?
(84 answers)
Closed 8 years ago.
Assume that I have this array:
a = [
[2823832908, 10071920],
[5384625228, 10924221],
[8488934028, 313411415],
[2823828588, 10071580],
[5224682868, 14919881],
[8155986228, 560217208],
[3458951628, 10071570],
[6382592388, 25064430],
[5021452668, 10924221],
[8827673748, 59397160],
[8647215588, 26343621]
]
and this array:
b = [
[8488934028, 313411415],
[8647215588, 26343621]
]
How can I get a new array that contains the values in array a that are not in array b, or how can I remove the values in array b from array a?
Create an empty result array.
Iterate over a, select its current element i.e. [2823832908, 10071920]
Compare current element for equality against each element of b , to compare equality
you can use JSON.stringify or .join to create string representation of arrays.
If the current element does not match any element of b, appent it to result array.
Repeat.
a = [
[2823832908, 10071920],
[5384625228, 10924221],
[8488934028, 313411415],
[2823828588, 10071580],
[5224682868, 14919881],
[8155986228, 560217208],
[3458951628, 10071570],
[6382592388, 25064430],
[5021452668, 10924221],
[8827673748, 59397160],
[8647215588, 26343621]
];
b = [
[8488934028, 313411415],
[8647215588, 26343621]
];
var result = [];
a.forEach(
function(elem,idx,arr)
{
var sig = JSON.stringify(elem);
var match = false;
for(var i=0;i<b.length;i++)
{
if(sig == JSON.stringify(b[i]))
{
match = true;
break;
}
}
if(match === false)
{
result.push(elem);
}
}
);
console.log(result);
demo : http://jsfiddle.net/Ag39M/4/
This is a bit tricky, principally because two arrays are not equal in Javascript, even if they have exactly the same keys.
You have to compare them manually, for example with this function by Tim Down.
You will then have to loop through the values in first array and compare them to every value in the second array.
The code might look like this:
var filtered = [];
// loop through every element in a
a.forEach(function(elA) {
// loop through every element in b
// if the elA is identical to any elB, some will immediately return true
// if elA is not identical to any elB, it will return false
var found = a.some(function(elB) {
return arraysIdentical(elA, elB);
});
// if we didn't find any equal ones, we'll add elA to the filtered array
if (!found) {
filtered.push(elA);
}
});
Note that this relies upon Array#forEach and Array#some. If you need to support older browsers, you'll need to shim them, with the polyfill code in those links.
Here's an implementation using undescore.js.
function diff(a1, a2) {
return _.filter(a1, function(e1) {
return !_.some(a2, function(e2) {
return _.isEqual(e1, e2);
});
});
}
Example:
var a = [ [ 1, 2 ], [ 3, 4 ], [ 5, 6, 7 ], [ 8 ], [ 9 ] ];
var b = [ [ 1, 2 ], [ 8 ], [ 9 ] ];
console.log(diff(a, b));
// [ [ 3, 4 ], [ 5, 6, 7 ] ]
function arra_diff(a, b)
{
var arr=[], diff=[];
for(var i=0;i<a.length;i++)
arr[a[i]]=true;
for(var i=0;i<b.length;i++)
if(arr[b[i]]) delete arr[b[i]];
else arr[b[i]]=true;
for(var k in arr)
diff.push(k);
return diff;
}
or
function arra_diff(d, c) { /* d=a,c=b */
for (var b = [], e = [], a = 0; a < d.length; a++) {
b[d[a]] = !0;
}
for (a = 0; a < c.length; a++) {
b[c[a]] ? delete b[c[a]] : b[c[a]] = !0;
}
for (var f in b) {
e.push(f);
}
return e;
};

Categories