Sorting Array based on another array [duplicate] - javascript

This question already has an answer here:
javascript sorting array based on another array
(1 answer)
Closed 6 years ago.
I have an array that could be made up of any the following values:
input = ['S-1','S-2','S-3','S-4','S-5','S-6','S-7','S-8'];
'input' can be made of any # of these values, without any duplicates. I'm trying to figure out how to sort 'input' according to the order of 'sortingArray':
sortingArray = ["S-1", "S-5", "S-2", "S-6", "S-3", "S-7", "S-4", "S-8"];
Any help would be greatly appreciated.

You can also use filter function and get copy of sortingArray including only values from input:
var input = ['S-1','S-2','S-3','S-4','S-5'];
var sortingArray = ["S-1", "S-5", "S-2", "S-6", "S-3", "S-7", "S-4", "S-8"];
var result = sortingArray.filter((el)=>(input.indexOf(el) > -1));
console.log(JSON.stringify(result));

Build a look-up object from your "sorting array":
var indexes = sortingArray.reduce(function(lookup, key, index) {
lookup[key] = index;
return lookup;
}, {});
Now you can use that in a comparator function:
input.sort(function(k1, k2) {
return indexes[k1] - indexes[k2];
});

Simple use with for loop.And apply the if condition for half of the array length.Then pass with new array
var input = ['S-1','S-2','S-3','S-4','S-5','S-6','S-7','S-8'];
var c =eval(input.length/2);
arr=[];
for(var i=0; i<input.length; i++){
if(i < c)
{
arr.push(input[i]);
arr.push(input[i+c]);
}
}
console.log(arr)

You could use an object with the indices of the sorted array and sort the new array with it.
var input = ['S-1', 'S-2', 'S-3', 'S-4', 'S-5', 'S-6', 'S-7', 'S-8'],
sortingArray = ["S-1", "S-5", "S-2", "S-6", "S-3", "S-7", "S-4", "S-8"],
order = Object.create(null);
sortingArray.forEach(function (a, i) { order[a] = i; });
input.sort(function (a, b) { return order[a] - order[b]; });
console.log(input);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Related

AngularJS objects in an array to new one [duplicate]

This question already has answers here:
From an array of objects, extract value of a property as array
(24 answers)
Closed 5 years ago.
DashboardService.GetDateList($scope.datestart, $scope.dateend).then(function (response) {
$scope.listdate = response.data;
});
i get an array list from this function above
[{"day":1,"sql_date":"2017-04-01T00:00:00"},
{"day":2,"sql_date":"2017-04-02T00:00:00"},
{"day":3,"sql_date":"2017-04-03T00:00:00"},
{"day":4,"sql_date":"2017-04-04T00:00:00"},
{"day":5,"sql_date":"2017-04-05T00:00:00"}
how can i push all day value from this array into a new one.
You can use Array#map to get the value of every day key.
var arr = [{"day":1,"sql_date":"2017-04-01T00:00:00"},{"day":2,"sql_date":"2017-04-02T00:00:00"},{"day":3,"sql_date":"2017-04-03T00:00:00"},{"day":4,"sql_date":"2017-04-04T00:00:00"},{"day":5,"sql_date":"2017-04-05T00:00:00"}],
newArr = arr.map(v => v.day);
console.log(newArr);
You can achieve this in different ways :
Using JavaScript for...in loop.
DEMO
var responseObj = [{"day":1,"sql_date":"2017-04-01T00:00:00"},
{"day":2,"sql_date":"2017-04-02T00:00:00"},
{"day":3,"sql_date":"2017-04-03T00:00:00"},
{"day":4,"sql_date":"2017-04-04T00:00:00"},
{"day":5,"sql_date":"2017-04-05T00:00:00"}];
var newArr = [];
for (var i in responseObj) {
newArr.push({"day":responseObj[i].day});
}
console.log(newArr);
Using Array map() method.
DEMO
var responseObj = [{"day":1,"sql_date":"2017-04-01T00:00:00"},
{"day":2,"sql_date":"2017-04-02T00:00:00"},
{"day":3,"sql_date":"2017-04-03T00:00:00"},
{"day":4,"sql_date":"2017-04-04T00:00:00"},
{"day":5,"sql_date":"2017-04-05T00:00:00"}];
var newArr = responseObj.map(function(item) {
return {"day":item.day};
});
console.log(newArr);
Using JavaScript for loop.
DEMO
var responseObj = [{"day":1,"sql_date":"2017-04-01T00:00:00"},
{"day":2,"sql_date":"2017-04-02T00:00:00"},
{"day":3,"sql_date":"2017-04-03T00:00:00"},
{"day":4,"sql_date":"2017-04-04T00:00:00"},
{"day":5,"sql_date":"2017-04-05T00:00:00"}];
var newArr = [];
for (var i = 0; i < responseObj.length; i++) {
newArr.push({"day": responseObj[i].day});
}
console.log(newArr);
Still you can use map instead of for loop. Please find the code snippet below
var arr = [{"day":1,"sql_date":"2017-04-01T00:00:00"},{"day":2,"sql_date":"2017-04-02T00:00:00"},{"day":3,"sql_date":"2017-04-03T00:00:00"},{"day":4,"sql_date":"2017-04-04T00:00:00"},{"day":5,"sql_date":"2017-04-05T00:00:00"}],
newArr = arr.map(function(obj) { return obj.day });
console.log(newArr);

Javascript Object order incorrect [duplicate]

This question already has answers here:
How to keep an Javascript object/array ordered while also maintaining key lookups?
(2 answers)
Closed 7 years ago.
I have got a function which retrieves an object.
This object has a property and a value. The property is numeric and starts at "-30" all the way up to "50"
The problem is that when I loop through this object the browser seems to order it starting at "0" instead of starting at the initial property of "-30"
I need to make sure the order is exactly the same as the object.
var colorOj = {
"-30":"#111","-29":"#131313", ..etc.., "0":"#333", ..etc..,
"50":"#555"
}
function makeList(object){
for (var i in object) {
console.log(i); // Returns 0,1,2,3,4,5
// I need a return of -30,-29,-28,..., 0, 1, 2 ...
}
}
makeList(colorObj);
As suggested by #Teemu, properties are not stored in any specific order. But you can print them in any order using specific sort function accordingly.
Code
var obj = {};
for (var i = 5; i > -5; i--) {
obj[i * 10] = i * 10;
}
// Sort and get all keys...
var keys = Object.keys(obj).sort(function(a, b) {
return parseInt(a) - parseInt(b);
});
console.log(keys)
// Loop over keys to print values of each property
keys.forEach(function(item) {
console.log(item, obj[item]);
})
You can do something like this maybe:
var colorOj = {
"-30":"#111","-29":"#131313", "0":"#333",
"50":"#555"
};
var keys = Object.keys(colorOj).sort(function(a,b){return a - b})
for(var i = 0; i < keys.length;i++){console.log(keys[i])}
This way you can get every key in the object. Then sort it however you like(the sort function in javascript can take a compare function as a parameter look -> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)

How do I sort one array by the corresponding values in another array?

I have two arrays. The first is for strings and the second is an array for their number of occurrences.
I am trying to get the top 10 most occurrences of words in the first array. I sorted it but somehow I only sort it alphabetically and the second array respectively corresponds to their number of occurrences.
How can I sort the second array from biggest to lowest and, at the same time, sort the first array that match the order of the second?
I'm having trouble inserting my json to my highcharts and I found out why, the numbers should be in square brackets [] I tried already inserting [] in 1 but still does not work please see my post I edit it
this is the data that i should insert in the highchart
[{"name":"#murrayftw","data":[46]},
{"name":"#job","data":[37]},
{"name":"#jobs","data":[25]},
{"name":"#favnashvine","data":[16]},
{"name":"#rollersmusicawards","data":[14]},
{"name":"#soa","data":[13]},
{"name":"#tweetmyjobs","data":[12]},
{"name":"#sman1boyolangu","data":[12]},
{"name":"#supernatural200thepisode","data":[12]},
{"name":"#veteransday","data":[12]}]
Try using a custom compare function with your .sort() call! Check out the documentation here.
I would, in this example (probably not the best way):
Have the unsorted "count" array
Have the unsorted word array
Sort the word array (with a custom function described below)
Sort the count array (no custom function)
The custom compare function would probably be a simple lookup and return the corresponding value in the unsorted count array. (i.e. if the word "a" is 0th index and its relevant count amount is in the 0th index of the count array, return count[0])
If you cannot work with an object try using nested for loops:
var array1 = ['z', 'd', 'e', 'f', 't'], arr1Count = array1.length;
var array2 = [1, 12, 5, 7, 3];
var sortedArray2 = array2.sort(function(x, y) {return y - x});
var i, j, sortedArray1 = [];
for (i = 0; i < arr1Count; i++) {
for (j = 0; j < arr1Count; j++) {
if (array2[j] === sortedArray2[i]) sortedArray1.push(array1[j]); //iterate through the unsorted numeric array (array2) and when it matches the sortedArray2, push this index of array1 into the sortedArray1
}
}
This will create an array of objects that are then sorted by count.
var hashtags = {},
counts = [];
for (var i in data)
{
if(data[i].lang == "en")
{
for (var j in data[i].entities.hashtags)
{
var text = data[i].entities.hashtags[j].text;
if(text) {
if(hashtags[text]) {
hashtags[text].data[0]++;
} else {
hashtags[text] = {
name: text,
data: [1]
};
counts.push(hashtags[text]);
}
}
}
}
}
counts.sort(function(a, b) { return b.data[0] - a.data[0]; });
Simple - don't use 2 arrays but one collection which every element is an object
I took the basics from this post: Sorting JavaScript Object by property value
and completed the demo:
var collection = {car:300, bike:60, motorbike:200, airplane:1000, helicopter:400, rocket:8*60*60}
var sortable = [];
for (var item in collection)
sortable.push([item, collection[item]])
sortable.sort(function(a, b) {return a[1] - b[1]})
collection = {};
for (var i in sortable)
{
collection[sortable[i][0]] = sortable[i][1];
}
console.log(collection);

Filtering a JavaScript array [duplicate]

This question already has an answer here:
How to filter a javascript object array with variable parameters
(1 answer)
Closed 9 years ago.
I am looking for a way to filter my JavaScript Array() columns where the parentId is equal to a variable passed into the method.
// Array decleration
var columns = []; // Columns
//...
for (var i1 in columns) {
if (columns[i1].parentId == listItem) {
//...
Could anybody recommend the easiest way to filter this using either plain JavaScript or jQuery to avoid using the if statement as shown above?
var filteredColumns = columns.filter(function(column) {
return column.parentId == listItem;
});
array = [1,2,3,4,5];
result = $.grep(array, function(n,i) {
return n > 3;
});
This will return an array of filtered elements where the results are greater than 3. Here n is the element in consideration, and i the index of the element. So as per your requirement, the code can run like this:
resultArray = $.grep(columns,function(n,i) {
return n == parentId;
});
Use ES5 Array's filter method:
var filtered = columns.filter(function (item) {
return item.parentId === listItem
});
In the link above there is also a shim for old browsers.
You can also doing that manually:
var filtered = [];
for (var i = 0, item; item = columns[i++];)
if (item.parentId === listItem) filtered.push(item);
Don't use for…in to iterate over Array.

Javascript array sort and unique

I have a JavaScript array like this:
var myData=['237','124','255','124','366','255'];
I need the array elements to be unique and sorted:
myData[0]='124';
myData[1]='237';
myData[2]='255';
myData[3]='366';
Even though the members of array look like integers, they're not integers, since I have already converted each to be string:
var myData[0]=num.toString();
//...and so on.
Is there any way to do all of these tasks in JavaScript?
This is actually very simple. It is much easier to find unique values, if the values are sorted first:
function sort_unique(arr) {
if (arr.length === 0) return arr;
arr = arr.sort(function (a, b) { return a*1 - b*1; });
var ret = [arr[0]];
for (var i = 1; i < arr.length; i++) { //Start loop at 1: arr[0] can never be a duplicate
if (arr[i-1] !== arr[i]) {
ret.push(arr[i]);
}
}
return ret;
}
console.log(sort_unique(['237','124','255','124','366','255']));
//["124", "237", "255", "366"]
You can now achieve the result in just one line of code.
Using new Set to reduce the array to unique set of values.
Apply the sort method after to order the string values.
var myData=['237','124','255','124','366','255']
var uniqueAndSorted = [...new Set(myData)].sort()
UPDATED for newer methods introduced in JavaScript since time of question.
This might be adequate in circumstances where you can't define the function in advance (like in a bookmarklet):
myData.sort().filter(function(el,i,a){return i===a.indexOf(el)})
Here's my (more modern) approach using Array.protoype.reduce():
[2, 1, 2, 3].reduce((a, x) => a.includes(x) ? a : [...a, x], []).sort()
// returns [1, 2, 3]
Edit: More performant version as pointed out in the comments:
arr.sort().filter((x, i, a) => !i || x != a[i-1])
function sort_unique(arr) {
return arr.sort().filter(function(el,i,a) {
return (i==a.indexOf(el));
});
}
How about:
array.sort().filter(function(elem, index, arr) {
return index == arr.length - 1 || arr[index + 1] != elem
})
This is similar to #loostro answer but instead of using indexOf which will reiterate the array for each element to verify that is the first found, it just checks that the next element is different than the current.
Try using an external library like underscore
var f = _.compose(_.uniq, function(array) {
return _.sortBy(array, _.identity);
});
var sortedUnique = f(array);
This relies on _.compose, _.uniq, _.sortBy, _.identity
See live example
What is it doing?
We want a function that takes an array and then returns a sorted array with the non-unique entries removed. This function needs to do two things, sorting and making the array unique.
This is a good job for composition, so we compose the unique & sort function together. _.uniq can just be applied on the array with one argument so it's just passed to _.compose
the _.sortBy function needs a sorting conditional functional. it expects a function that returns a value and the array will be sorted on that value. Since the value that we are ordering it by is the value in the array we can just pass the _.identity function.
We now have a composition of a function that (takes an array and returns a unique array) and a function that (takes an array and returns a sorted array, sorted by their values).
We simply apply the composition on the array and we have our uniquely sorted array.
This function doesn't fail for more than two duplicates values:
function unique(arr) {
var a = [];
var l = arr.length;
for(var i=0; i<l; i++) {
for(var j=i+1; j<l; j++) {
// If a[i] is found later in the array
if (arr[i] === arr[j])
j = ++i;
}
a.push(arr[i]);
}
return a;
};
Here is a simple one liner with O(N), no complicated loops necessary.
> Object.keys(['a', 'b', 'a'].reduce((l, r) => l[r] = l, {})).sort()
[ 'a', 'b' ]
Explanation
Original data set, assume its coming in from an external function
const data = ['a', 'b', 'a']
We want to group all the values onto an object as keys as the method of deduplication. So we use reduce with an object as the default value:
[].reduce(fn, {})
The next step is to create a reduce function which will put the values in the array onto the object. The end result is an object with a unique set of keys.
const reduced = data.reduce((l, r) => l[r] = l, {})
We set l[r] = l because in javascript the value of the assignment expression is returned when an assignment statement is used as an expression. l is the accumulator object and r is the key value. You can also use Object.assign(l, { [r]: (l[r] || 0) + 1 }) or something similar to get the count of each value if that was important to you.
Next we want to get the keys of that object
const keys = Object.keys(reduced)
Then simply use the built-in sort
console.log(keys.sort())
Which is the set of unique values of the original array, sorted
['a', 'b']
The solution in a more elegant way.
var myData=['237','124','255','124','366','255'];
console.log(Array.from(new Set(myData)).sort((a,b) => a - b));
I know the question is very old, but maybe someone will come in handy
A way to use a custom sort function
//func has to return 0 in the case in which they are equal
sort_unique = function(arr,func) {
func = func || function (a, b) {
return a*1 - b*1;
};
arr = arr.sort(func);
var ret = [arr[0]];
for (var i = 1; i < arr.length; i++) {
if (func(arr[i-1],arr[i]) != 0)
ret.push(arr[i]);
}
}
return ret;
}
Example: desc order for an array of objects
MyArray = sort_unique(MyArray , function(a,b){
return b.iterator_internal*1 - a.iterator_internal*1;
});
No redundant "return" array, no ECMA5 built-ins (I'm pretty sure!) and simple to read.
function removeDuplicates(target_array) {
target_array.sort();
var i = 0;
while(i < target_array.length) {
if(target_array[i] === target_array[i+1]) {
target_array.splice(i+1,1);
}
else {
i += 1;
}
}
return target_array;
}
I guess I'll post this answer for some variety. This technique for purging duplicates is something I picked up on for a project in Flash I'm currently working on about a month or so ago.
What you do is make an object and fill it with both a key and a value utilizing each array item. Since duplicate keys are discarded, duplicates are removed.
var nums = [1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10];
var newNums = purgeArray(nums);
function purgeArray(ar)
{
var obj = {};
var temp = [];
for(var i=0;i<ar.length;i++)
{
obj[ar[i]] = ar[i];
}
for (var item in obj)
{
temp.push(obj[item]);
}
return temp;
}
There's already 5 other answers, so I don't see a need to post a sorting function.
// Another way, that does not rearrange the original Array
// and spends a little less time handling duplicates.
function uniqueSort(arr, sortby){
var A1= arr.slice();
A1= typeof sortby== 'function'? A1.sort(sortby): A1.sort();
var last= A1.shift(), next, A2= [last];
while(A1.length){
next= A1.shift();
while(next=== last) next= A1.shift();
if(next!=undefined){
A2[A2.length]= next;
last= next;
}
}
return A2;
}
var myData= ['237','124','255','124','366','255','100','1000'];
uniqueSort(myData,function(a,b){return a-b})
// the ordinary sort() returns the same array as the number sort here,
// but some strings of digits do not sort so nicely numerical.
function sort() only is only good if your number has same digit, example:
var myData = ["3","11","1","2"]
will return;
var myData = ["1","11","2","3"]
and here improvement for function from mrmonkington
myData.sort().sort(function(a,b){return a - b;}).filter(function(el,i,a){if(i==a.indexOf(el) & el.length>0)return 1;return 0;})
the above function will also delete empty array and you can checkout the demo below
http://jsbin.com/ahojip/2/edit
O[N^2] solutions are bad, especially when the data is already sorted, there is no need to do two nested loops for removing duplicates. One loop and comparing to the previous element will work great.
A simple solution with O[] of sort() would suffice. My solution is:
function sortUnique(arr, compareFunction) {
let sorted = arr.sort(compareFunction);
let result = sorted.filter(compareFunction
? function(val, i, a) { return (i == 0 || compareFunction(a[i-1], val) != 0); }
: function(val, i, a) { return (i == 0 || a[i-1] !== val); }
);
return result;
}
BTW, can do something like this to have Array.sortUnique() method:
Array.prototype.sortUnique = function(compareFunction) {return sortUnique(this, compareFunction); }
Furthermore, sort() could be modified to remove second element if compare() function returns 0 (equal elements), though that code can become messy (need to revise loop boundaries in the flight). Besides, I stay away from making my own sort() functions in interpreted languages, since it will most certainly degrade the performance. So this addition is for the ECMA 2019+ consideration.
The fastest and simpleness way to do this task.
const N = Math.pow(8, 8)
let data = Array.from({length: N}, () => Math.floor(Math.random() * N))
let newData = {}
let len = data.length
// the magic
while (len--) {
newData[data[len]] = true
}
var array = [2,5,4,2,5,9,4,2,6,9,0,5,4,7,8];
var unique_array = [...new Set(array)]; // [ 2, 5, 4, 9, 6, 0, 7, 8 ]
var uniqueWithSorted = unique_array.sort();
console.log(uniqueWithSorted);
output = [ 0, 2, 4, 5, 6, 7, 8, 9 ]
Here, we used only Set for removing duplicity from the array and then used sort for sorting array in ascending order.
I'm afraid you can't combine these functions, ie. you gotta do something like this:-
myData.unique().sort();
Alternatively you can implement a kind of sortedset (as available in other languages) - which carries both the notion of sorting and removing duplicates, as you require.
Hope this helps.
References:-
Array.sort
Array.unique

Categories

Resources