Related
Is it possible to sort and rearrange an array that looks like this:
itemsArray = [
['Anne', 'a'],
['Bob', 'b'],
['Henry', 'b'],
['Andrew', 'd'],
['Jason', 'c'],
['Thomas', 'b']
]
to match the arrangement of this array:
sortingArr = [ 'b', 'c', 'b', 'b', 'a', 'd' ]
Unfortunately, I don’t have any IDs to keep track on. I would need to priority the items-array to match the sortingArr as close as possible.
Update:
Here is the output I’m looking for:
itemsArray = [
['Bob', 'b'],
['Jason', 'c'],
['Henry', 'b'],
['Thomas', 'b']
['Anne', 'a'],
['Andrew', 'd'],
]
Any idea how this can be done?
One-Line answer.
itemsArray.sort(function(a, b){
return sortingArr.indexOf(a) - sortingArr.indexOf(b);
});
Or even shorter:
itemsArray.sort((a, b) => sortingArr.indexOf(a) - sortingArr.indexOf(b));
Something like:
items = [
['Anne', 'a'],
['Bob', 'b'],
['Henry', 'b'],
['Andrew', 'd'],
['Jason', 'c'],
['Thomas', 'b']
]
sorting = [ 'b', 'c', 'b', 'b', 'c', 'd' ];
result = []
sorting.forEach(function(key) {
var found = false;
items = items.filter(function(item) {
if(!found && item[1] == key) {
result.push(item);
found = true;
return false;
} else
return true;
})
})
result.forEach(function(item) {
document.writeln(item[0]) /// Bob Jason Henry Thomas Andrew
})
Here's a shorter code, but it destroys the sorting array:
result = items.map(function(item) {
var n = sorting.indexOf(item[1]);
sorting[n] = '';
return [n, item]
}).sort().map(function(j) { return j[1] })
If you use the native array sort function, you can pass in a custom comparator to be used when sorting the array. The comparator should return a negative number if the first value is less than the second, zero if they're equal, and a positive number if the first value is greater.
So if I understand the example you're giving correctly, you could do something like:
function sortFunc(a, b) {
var sortingArr = [ 'b', 'c', 'b', 'b', 'c', 'd' ];
return sortingArr.indexOf(a[1]) - sortingArr.indexOf(b[1]);
}
itemsArray.sort(sortFunc);
Case 1: Original Question (No Libraries)
Plenty of other answers that work. :)
Case 2: Original Question (Lodash.js or Underscore.js)
var groups = _.groupBy(itemArray, 1);
var result = _.map(sortArray, function (i) { return groups[i].shift(); });
Case 3: Sort Array1 as if it were Array2
I'm guessing that most people came here looking for an equivalent to PHP's array_multisort (I did) so I thought I'd post that answer as well. There are a couple options:
1. There's an existing JS implementation of array_multisort(). Thanks to #Adnan for pointing it out in the comments. It is pretty large, though.
2. Write your own. (JSFiddle demo)
function refSort (targetData, refData) {
// Create an array of indices [0, 1, 2, ...N].
var indices = Object.keys(refData);
// Sort array of indices according to the reference data.
indices.sort(function(indexA, indexB) {
if (refData[indexA] < refData[indexB]) {
return -1;
} else if (refData[indexA] > refData[indexB]) {
return 1;
}
return 0;
});
// Map array of indices to corresponding values of the target array.
return indices.map(function(index) {
return targetData[index];
});
}
3. Lodash.js or Underscore.js (both popular, smaller libraries that focus on performance) offer helper functions that allow you to do this:
var result = _.chain(sortArray)
.pairs()
.sortBy(1)
.map(function (i) { return itemArray[i[0]]; })
.value();
...Which will (1) group the sortArray into [index, value] pairs, (2) sort them by the value (you can also provide a callback here), (3) replace each of the pairs with the item from the itemArray at the index the pair originated from.
this is probably too late but, you could also use some modified version of the code below in ES6 style. This code is for arrays like:
var arrayToBeSorted = [1,2,3,4,5];
var arrayWithReferenceOrder = [3,5,8,9];
The actual operation :
arrayToBeSorted = arrayWithReferenceOrder.filter(v => arrayToBeSorted.includes(v));
The actual operation in ES5 :
arrayToBeSorted = arrayWithReferenceOrder.filter(function(v) {
return arrayToBeSorted.includes(v);
});
Should result in arrayToBeSorted = [3,5]
Does not destroy the reference array.
function sortFunc(a, b) {
var sortingArr = ["A", "B", "C"];
return sortingArr.indexOf(a.type) - sortingArr.indexOf(b.type);
}
const itemsArray = [
{
type: "A",
},
{
type: "C",
},
{
type: "B",
},
];
console.log(itemsArray);
itemsArray.sort(sortFunc);
console.log(itemsArray);
Why not something like
//array1: array of elements to be sorted
//array2: array with the indexes
array1 = array2.map((object, i) => array1[object]);
The map function may not be available on all versions of Javascript
ES6
const arrayMap = itemsArray.reduce(
(accumulator, currentValue) => ({
...accumulator,
[currentValue[1]]: currentValue,
}),
{}
);
const result = sortingArr.map(key => arrayMap[key]);
More examples with different input arrays
I would use an intermediary object (itemsMap), thus avoiding quadratic complexity:
function createItemsMap(itemsArray) { // {"a": ["Anne"], "b": ["Bob", "Henry"], …}
var itemsMap = {};
for (var i = 0, item; (item = itemsArray[i]); ++i) {
(itemsMap[item[1]] || (itemsMap[item[1]] = [])).push(item[0]);
}
return itemsMap;
}
function sortByKeys(itemsArray, sortingArr) {
var itemsMap = createItemsMap(itemsArray), result = [];
for (var i = 0; i < sortingArr.length; ++i) {
var key = sortingArr[i];
result.push([itemsMap[key].shift(), key]);
}
return result;
}
See http://jsfiddle.net/eUskE/
var sortedArray = [];
for(var i=0; i < sortingArr.length; i++) {
var found = false;
for(var j=0; j < itemsArray.length && !found; j++) {
if(itemsArray[j][1] == sortingArr[i]) {
sortedArray.push(itemsArray[j]);
itemsArray.splice(j,1);
found = true;
}
}
}
http://jsfiddle.net/s7b2P/
Resulting order: Bob,Jason,Henry,Thomas,Anne,Andrew
In case you get here needing to do this with an array of objects, here is an adaptation of #Durgpal Singh's awesome answer:
const itemsArray = [
{ name: 'Anne', id: 'a' },
{ name: 'Bob', id: 'b' },
{ name: 'Henry', id: 'b' },
{ name: 'Andrew', id: 'd' },
{ name: 'Jason', id: 'c' },
{ name: 'Thomas', id: 'b' }
]
const sortingArr = [ 'b', 'c', 'b', 'b', 'a', 'd' ]
Object.keys(itemsArray).sort((a, b) => {
return sortingArr.indexOf(itemsArray[a].id) - sortingArr.indexOf(itemsArray[b].id);
})
let a = ['A', 'B', 'C' ]
let b = [3, 2, 1]
let c = [1.0, 5.0, 2.0]
// these array can be sorted by sorting order of b
const zip = rows => rows[0].map((_, c) => rows.map(row => row[c]))
const sortBy = (a, b, c) => {
const zippedArray = zip([a, b, c])
const sortedZipped = zippedArray.sort((x, y) => x[1] - y[1])
return zip(sortedZipped)
}
sortBy(a, b, c)
For getting a new ordered array, you could take a Map and collect all items with the wanted key in an array and map the wanted ordered keys by taking sifted element of the wanted group.
var itemsArray = [['Anne', 'a'], ['Bob', 'b'], ['Henry', 'b'], ['Andrew', 'd'], ['Jason', 'c'], ['Thomas', 'b']],
sortingArr = [ 'b', 'c', 'b', 'b', 'a', 'd' ],
map = itemsArray.reduce((m, a) => m.set(a[1], (m.get(a[1]) || []).concat([a])), new Map),
result = sortingArr.map(k => (map.get(k) || []).shift());
console.log(result);
I hope that I am helping someone, but if you are trying to sort an array of objects by another array on the first array's key, for example, you want to sort this array of objects:
const foo = [
{name: 'currency-question', key: 'value'},
{name: 'phone-question', key: 'value'},
{name: 'date-question', key: 'value'},
{name: 'text-question', key: 'value'}
];
by this array:
const bar = ['text-question', 'phone-question', 'currency-question', 'date-question'];
you can do so by:
foo.sort((a, b) => bar.indexOf(a.name) - bar.indexOf(b.name));
This is what I was looking for and I did for sorting an Array of Arrays based on another Array:
It's On^3 and might not be the best practice(ES6)
function sortArray(arr, arr1){
return arr.map(item => {
let a = [];
for(let i=0; i< arr1.length; i++){
for (const el of item) {
if(el == arr1[i]){
a.push(el);
}
}
}
return a;
});
}
const arr1 = ['fname', 'city', 'name'];
const arr = [['fname', 'city', 'name'],
['fname', 'city', 'name', 'name', 'city','fname']];
console.log(sortArray(arr,arr1));
It might help someone
I had to do this for a JSON payload I receive from an API, but it wasn't in the order I wanted it.
Array to be the reference array, the one you want the second array sorted by:
var columns = [
{last_name: "last_name"},
{first_name: "first_name"},
{book_description: "book_description"},
{book_id: "book_id"},
{book_number: "book_number"},
{due_date: "due_date"},
{loaned_out: "loaned_out"}
];
I did these as objects because these will have other properties eventually.
Created array:
var referenceArray= [];
for (var key in columns) {
for (var j in columns[key]){
referenceArray.push(j);
}
}
Used this with result set from database. I don't know how efficient it is but with the few number of columns I used, it worked fine.
result.forEach((element, index, array) => {
var tr = document.createElement('tr');
for (var i = 0; i < referenceArray.length - 1; i++) {
var td = document.createElement('td');
td.innerHTML = element[referenceArray[i]];
tr.appendChild(td);
}
tableBody.appendChild(tr);
});
let sortedOrder = [ 'b', 'c', 'b', 'b' ]
let itemsArray = [
['Anne', 'a'],
['Bob', 'b'],
['Henry', 'b'],
['Andrew', 'd'],
['Jason', 'c'],
['Thomas', 'b']
]
a.itemsArray(function (a, b) {
let A = a[1]
let B = b[1]
if(A != undefined)
A = A.toLowerCase()
if(B != undefined)
B = B.toLowerCase()
let indA = sortedOrder.indexOf(A)
let indB = sortedOrder.indexOf(B)
if (indA == -1 )
indA = sortedOrder.length-1
if( indB == -1)
indB = sortedOrder.length-1
if (indA < indB ) {
return -1;
} else if (indA > indB) {
return 1;
}
return 0;
})
This solution will append the objects at the end if the sorting key is not present in reference array
const result = sortingArr.map((i) => {
const pos = itemsArray.findIndex(j => j[1] === i);
const item = itemsArray[pos];
itemsArray.splice(pos, 1);
return item;
});
this should works:
var i,search, itemsArraySorted = [];
while(sortingArr.length) {
search = sortingArr.shift();
for(i = 0; i<itemsArray.length; i++) {
if(itemsArray[i][1] == search) {
itemsArraySorted.push(itemsArray[i]);
break;
}
}
}
itemsArray = itemsArraySorted;
You could try this method.
const sortListByRanking = (rankingList, listToSort) => {
let result = []
for (let id of rankingList) {
for (let item of listToSort) {
if (item && item[1] === id) {
result.push(item)
}
}
}
return result
}
with numerical sortingArr:
itemsArray.sort(function(a, b){
return sortingArr[itemsArray.indexOf(a)] - sortingArr[itemsArray.indexOf(b)];
});
This seems to work for me:
var outputArray=['10','6','8','10','4','6','2','10','4','0','2','10','0'];
var template=['0','2','4','6','8','10'];
var temp=[];
for(i=0;i<template.length;i++) {
for(x=0;x<outputArray.length;x++){
if(template[i] == outputArray[x]) temp.push(outputArray[x])
};
}
outputArray = temp;
alert(outputArray)
Use the $.inArray() method from jQuery. You then could do something like this
var sortingArr = [ 'b', 'c', 'b', 'b', 'c', 'd' ];
var newSortedArray = new Array();
for(var i=sortingArr.length; i--;) {
var foundIn = $.inArray(sortingArr[i], itemsArray);
newSortedArray.push(itemsArray[foundIn]);
}
Use intersection of two arrays.
Ex:
var sortArray = ['a', 'b', 'c', 'd', 'e'];
var arrayToBeSort = ['z', 's', 'b', 'e', 'a'];
_.intersection(sortArray, arrayToBeSort)
=> ['a', 'b', 'e']
if 'z and 's' are out of range of first array, append it at the end of result
this.arrToBeSorted = this.arrToBeSorted.sort(function(a, b){
return uppthis.sorrtingByArray.findIndex(x => x.Id == a.ByPramaeterSorted) - uppthis.sorrtingByArray.findIndex(x => x.Id == b.ByPramaeterSorted);
});
You can do something like this:
function getSorted(itemsArray , sortingArr ) {
var result = [];
for(var i=0; i<arr.length; i++) {
result[i] = arr[sortArr[i]];
}
return result;
}
You can test it out here.
Note: this assumes the arrays you pass in are equivalent in size, you'd need to add some additional checks if this may not be the case.
refer link
refer
Is it possible to sort and rearrange an array that looks like this:
itemsArray = [
['Anne', 'a'],
['Bob', 'b'],
['Henry', 'b'],
['Andrew', 'd'],
['Jason', 'c'],
['Thomas', 'b']
]
to match the arrangement of this array:
sortingArr = [ 'b', 'c', 'b', 'b', 'a', 'd' ]
Unfortunately, I don’t have any IDs to keep track on. I would need to priority the items-array to match the sortingArr as close as possible.
Update:
Here is the output I’m looking for:
itemsArray = [
['Bob', 'b'],
['Jason', 'c'],
['Henry', 'b'],
['Thomas', 'b']
['Anne', 'a'],
['Andrew', 'd'],
]
Any idea how this can be done?
One-Line answer.
itemsArray.sort(function(a, b){
return sortingArr.indexOf(a) - sortingArr.indexOf(b);
});
Or even shorter:
itemsArray.sort((a, b) => sortingArr.indexOf(a) - sortingArr.indexOf(b));
Something like:
items = [
['Anne', 'a'],
['Bob', 'b'],
['Henry', 'b'],
['Andrew', 'd'],
['Jason', 'c'],
['Thomas', 'b']
]
sorting = [ 'b', 'c', 'b', 'b', 'c', 'd' ];
result = []
sorting.forEach(function(key) {
var found = false;
items = items.filter(function(item) {
if(!found && item[1] == key) {
result.push(item);
found = true;
return false;
} else
return true;
})
})
result.forEach(function(item) {
document.writeln(item[0]) /// Bob Jason Henry Thomas Andrew
})
Here's a shorter code, but it destroys the sorting array:
result = items.map(function(item) {
var n = sorting.indexOf(item[1]);
sorting[n] = '';
return [n, item]
}).sort().map(function(j) { return j[1] })
If you use the native array sort function, you can pass in a custom comparator to be used when sorting the array. The comparator should return a negative number if the first value is less than the second, zero if they're equal, and a positive number if the first value is greater.
So if I understand the example you're giving correctly, you could do something like:
function sortFunc(a, b) {
var sortingArr = [ 'b', 'c', 'b', 'b', 'c', 'd' ];
return sortingArr.indexOf(a[1]) - sortingArr.indexOf(b[1]);
}
itemsArray.sort(sortFunc);
Case 1: Original Question (No Libraries)
Plenty of other answers that work. :)
Case 2: Original Question (Lodash.js or Underscore.js)
var groups = _.groupBy(itemArray, 1);
var result = _.map(sortArray, function (i) { return groups[i].shift(); });
Case 3: Sort Array1 as if it were Array2
I'm guessing that most people came here looking for an equivalent to PHP's array_multisort (I did) so I thought I'd post that answer as well. There are a couple options:
1. There's an existing JS implementation of array_multisort(). Thanks to #Adnan for pointing it out in the comments. It is pretty large, though.
2. Write your own. (JSFiddle demo)
function refSort (targetData, refData) {
// Create an array of indices [0, 1, 2, ...N].
var indices = Object.keys(refData);
// Sort array of indices according to the reference data.
indices.sort(function(indexA, indexB) {
if (refData[indexA] < refData[indexB]) {
return -1;
} else if (refData[indexA] > refData[indexB]) {
return 1;
}
return 0;
});
// Map array of indices to corresponding values of the target array.
return indices.map(function(index) {
return targetData[index];
});
}
3. Lodash.js or Underscore.js (both popular, smaller libraries that focus on performance) offer helper functions that allow you to do this:
var result = _.chain(sortArray)
.pairs()
.sortBy(1)
.map(function (i) { return itemArray[i[0]]; })
.value();
...Which will (1) group the sortArray into [index, value] pairs, (2) sort them by the value (you can also provide a callback here), (3) replace each of the pairs with the item from the itemArray at the index the pair originated from.
this is probably too late but, you could also use some modified version of the code below in ES6 style. This code is for arrays like:
var arrayToBeSorted = [1,2,3,4,5];
var arrayWithReferenceOrder = [3,5,8,9];
The actual operation :
arrayToBeSorted = arrayWithReferenceOrder.filter(v => arrayToBeSorted.includes(v));
The actual operation in ES5 :
arrayToBeSorted = arrayWithReferenceOrder.filter(function(v) {
return arrayToBeSorted.includes(v);
});
Should result in arrayToBeSorted = [3,5]
Does not destroy the reference array.
function sortFunc(a, b) {
var sortingArr = ["A", "B", "C"];
return sortingArr.indexOf(a.type) - sortingArr.indexOf(b.type);
}
const itemsArray = [
{
type: "A",
},
{
type: "C",
},
{
type: "B",
},
];
console.log(itemsArray);
itemsArray.sort(sortFunc);
console.log(itemsArray);
Why not something like
//array1: array of elements to be sorted
//array2: array with the indexes
array1 = array2.map((object, i) => array1[object]);
The map function may not be available on all versions of Javascript
ES6
const arrayMap = itemsArray.reduce(
(accumulator, currentValue) => ({
...accumulator,
[currentValue[1]]: currentValue,
}),
{}
);
const result = sortingArr.map(key => arrayMap[key]);
More examples with different input arrays
I would use an intermediary object (itemsMap), thus avoiding quadratic complexity:
function createItemsMap(itemsArray) { // {"a": ["Anne"], "b": ["Bob", "Henry"], …}
var itemsMap = {};
for (var i = 0, item; (item = itemsArray[i]); ++i) {
(itemsMap[item[1]] || (itemsMap[item[1]] = [])).push(item[0]);
}
return itemsMap;
}
function sortByKeys(itemsArray, sortingArr) {
var itemsMap = createItemsMap(itemsArray), result = [];
for (var i = 0; i < sortingArr.length; ++i) {
var key = sortingArr[i];
result.push([itemsMap[key].shift(), key]);
}
return result;
}
See http://jsfiddle.net/eUskE/
var sortedArray = [];
for(var i=0; i < sortingArr.length; i++) {
var found = false;
for(var j=0; j < itemsArray.length && !found; j++) {
if(itemsArray[j][1] == sortingArr[i]) {
sortedArray.push(itemsArray[j]);
itemsArray.splice(j,1);
found = true;
}
}
}
http://jsfiddle.net/s7b2P/
Resulting order: Bob,Jason,Henry,Thomas,Anne,Andrew
In case you get here needing to do this with an array of objects, here is an adaptation of #Durgpal Singh's awesome answer:
const itemsArray = [
{ name: 'Anne', id: 'a' },
{ name: 'Bob', id: 'b' },
{ name: 'Henry', id: 'b' },
{ name: 'Andrew', id: 'd' },
{ name: 'Jason', id: 'c' },
{ name: 'Thomas', id: 'b' }
]
const sortingArr = [ 'b', 'c', 'b', 'b', 'a', 'd' ]
Object.keys(itemsArray).sort((a, b) => {
return sortingArr.indexOf(itemsArray[a].id) - sortingArr.indexOf(itemsArray[b].id);
})
let a = ['A', 'B', 'C' ]
let b = [3, 2, 1]
let c = [1.0, 5.0, 2.0]
// these array can be sorted by sorting order of b
const zip = rows => rows[0].map((_, c) => rows.map(row => row[c]))
const sortBy = (a, b, c) => {
const zippedArray = zip([a, b, c])
const sortedZipped = zippedArray.sort((x, y) => x[1] - y[1])
return zip(sortedZipped)
}
sortBy(a, b, c)
For getting a new ordered array, you could take a Map and collect all items with the wanted key in an array and map the wanted ordered keys by taking sifted element of the wanted group.
var itemsArray = [['Anne', 'a'], ['Bob', 'b'], ['Henry', 'b'], ['Andrew', 'd'], ['Jason', 'c'], ['Thomas', 'b']],
sortingArr = [ 'b', 'c', 'b', 'b', 'a', 'd' ],
map = itemsArray.reduce((m, a) => m.set(a[1], (m.get(a[1]) || []).concat([a])), new Map),
result = sortingArr.map(k => (map.get(k) || []).shift());
console.log(result);
I hope that I am helping someone, but if you are trying to sort an array of objects by another array on the first array's key, for example, you want to sort this array of objects:
const foo = [
{name: 'currency-question', key: 'value'},
{name: 'phone-question', key: 'value'},
{name: 'date-question', key: 'value'},
{name: 'text-question', key: 'value'}
];
by this array:
const bar = ['text-question', 'phone-question', 'currency-question', 'date-question'];
you can do so by:
foo.sort((a, b) => bar.indexOf(a.name) - bar.indexOf(b.name));
This is what I was looking for and I did for sorting an Array of Arrays based on another Array:
It's On^3 and might not be the best practice(ES6)
function sortArray(arr, arr1){
return arr.map(item => {
let a = [];
for(let i=0; i< arr1.length; i++){
for (const el of item) {
if(el == arr1[i]){
a.push(el);
}
}
}
return a;
});
}
const arr1 = ['fname', 'city', 'name'];
const arr = [['fname', 'city', 'name'],
['fname', 'city', 'name', 'name', 'city','fname']];
console.log(sortArray(arr,arr1));
It might help someone
I had to do this for a JSON payload I receive from an API, but it wasn't in the order I wanted it.
Array to be the reference array, the one you want the second array sorted by:
var columns = [
{last_name: "last_name"},
{first_name: "first_name"},
{book_description: "book_description"},
{book_id: "book_id"},
{book_number: "book_number"},
{due_date: "due_date"},
{loaned_out: "loaned_out"}
];
I did these as objects because these will have other properties eventually.
Created array:
var referenceArray= [];
for (var key in columns) {
for (var j in columns[key]){
referenceArray.push(j);
}
}
Used this with result set from database. I don't know how efficient it is but with the few number of columns I used, it worked fine.
result.forEach((element, index, array) => {
var tr = document.createElement('tr');
for (var i = 0; i < referenceArray.length - 1; i++) {
var td = document.createElement('td');
td.innerHTML = element[referenceArray[i]];
tr.appendChild(td);
}
tableBody.appendChild(tr);
});
let sortedOrder = [ 'b', 'c', 'b', 'b' ]
let itemsArray = [
['Anne', 'a'],
['Bob', 'b'],
['Henry', 'b'],
['Andrew', 'd'],
['Jason', 'c'],
['Thomas', 'b']
]
a.itemsArray(function (a, b) {
let A = a[1]
let B = b[1]
if(A != undefined)
A = A.toLowerCase()
if(B != undefined)
B = B.toLowerCase()
let indA = sortedOrder.indexOf(A)
let indB = sortedOrder.indexOf(B)
if (indA == -1 )
indA = sortedOrder.length-1
if( indB == -1)
indB = sortedOrder.length-1
if (indA < indB ) {
return -1;
} else if (indA > indB) {
return 1;
}
return 0;
})
This solution will append the objects at the end if the sorting key is not present in reference array
const result = sortingArr.map((i) => {
const pos = itemsArray.findIndex(j => j[1] === i);
const item = itemsArray[pos];
itemsArray.splice(pos, 1);
return item;
});
this should works:
var i,search, itemsArraySorted = [];
while(sortingArr.length) {
search = sortingArr.shift();
for(i = 0; i<itemsArray.length; i++) {
if(itemsArray[i][1] == search) {
itemsArraySorted.push(itemsArray[i]);
break;
}
}
}
itemsArray = itemsArraySorted;
You could try this method.
const sortListByRanking = (rankingList, listToSort) => {
let result = []
for (let id of rankingList) {
for (let item of listToSort) {
if (item && item[1] === id) {
result.push(item)
}
}
}
return result
}
with numerical sortingArr:
itemsArray.sort(function(a, b){
return sortingArr[itemsArray.indexOf(a)] - sortingArr[itemsArray.indexOf(b)];
});
This seems to work for me:
var outputArray=['10','6','8','10','4','6','2','10','4','0','2','10','0'];
var template=['0','2','4','6','8','10'];
var temp=[];
for(i=0;i<template.length;i++) {
for(x=0;x<outputArray.length;x++){
if(template[i] == outputArray[x]) temp.push(outputArray[x])
};
}
outputArray = temp;
alert(outputArray)
Use the $.inArray() method from jQuery. You then could do something like this
var sortingArr = [ 'b', 'c', 'b', 'b', 'c', 'd' ];
var newSortedArray = new Array();
for(var i=sortingArr.length; i--;) {
var foundIn = $.inArray(sortingArr[i], itemsArray);
newSortedArray.push(itemsArray[foundIn]);
}
Use intersection of two arrays.
Ex:
var sortArray = ['a', 'b', 'c', 'd', 'e'];
var arrayToBeSort = ['z', 's', 'b', 'e', 'a'];
_.intersection(sortArray, arrayToBeSort)
=> ['a', 'b', 'e']
if 'z and 's' are out of range of first array, append it at the end of result
this.arrToBeSorted = this.arrToBeSorted.sort(function(a, b){
return uppthis.sorrtingByArray.findIndex(x => x.Id == a.ByPramaeterSorted) - uppthis.sorrtingByArray.findIndex(x => x.Id == b.ByPramaeterSorted);
});
You can do something like this:
function getSorted(itemsArray , sortingArr ) {
var result = [];
for(var i=0; i<arr.length; i++) {
result[i] = arr[sortArr[i]];
}
return result;
}
You can test it out here.
Note: this assumes the arrays you pass in are equivalent in size, you'd need to add some additional checks if this may not be the case.
refer link
refer
What's the best way to mix multiple arrays like the way in the image below,
PS:
I don't know what will be the length of each array
Arrays will contain +10000 elements
There will be more than 3 arrays
I made a solution for it but I'm looking for any better solution
Here's my Own solution, I was looking for any better idea
import { compact, flattenDeep } from "lodash/array";
export const doTheMagic = master => {
const longest = master.reduce((p, c, i, a) => (a[p].length > c.length ? p : i), 0);
const mixed = master[longest].map((i, k) => {
return master.map((o, a) => {
if (master[a][k]) return master[a][k];
});
});
const flaten = flattenDeep(mixed);
return compact(flaten);// to remove falsey values
};
const one = [1,2,3];
const two = ['a','b','c','d','e'];
const three = ['k','l','m','n'];
const mix = doTheMagic([one,two,three]);
console.log('mix: ', mix);
You could use lodash for your solution.
const { flow, zip, flatten, filter} = _
const doTheMagic = flow(
zip,
flatten,
filter
)
const one = [1, 2, 3]
const two = ['😕', '🤯', '🙈', '🙊', '🙉', '😃']
const three = ['foo', 'bar', 'wow', 'okay']
const result = doTheMagic(one, two, three)
console.log(result)
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.15/lodash.min.js"></script>
Works with different length of arrays and makes use of functional programming for elegant code.
Here's a codepen to run: https://codepen.io/matteodem/pen/mddQrwe
Here's my Own solution, I was looking for any better idea
import { compact, flattenDeep } from "lodash/array";
export const doTheMagic = master => {
const longest = master.reduce((p, c, i, a) => (a[p].length > c.length ? p : i), 0);
const mixed = master[longest].map((i, k) => {
return master.map((o, a) => {
if (master[a][k]) return master[a][k];
});
});
const flaten = flattenDeep(mixed);
return compact(flaten);// to remove falsey values
};
const one = [1,2,3];
const two = ['a','b','c','d','e'];
const three = ['k','l','m','n'];
const mix = doTheMagic([one,two,three]);
console.log('mix: ', mix);
let a1 = [1, 2, 3, 4, 5];
let a2 = ["🏯", "🏜", "🏭", "🎢", "🌠", "🏗"];
let a3 = ['one', 'two', 'three', 'four', 'five'];
const doTheMagic = arrayOfArrays => {
let maxLength = 0;
let result = [];
for (arr in arrayOfArrays) {
maxLength = Math.max(maxLength, arrayOfArrays[arr].length);
}
for (let i = 0; i < maxLength; i++) {
for (let j = 0; j < arrayOfArrays.length; j++) {
if (arrayOfArrays[j][i]) {
result.push(arrayOfArrays[j][i]);
}
}
}
return result;
}
console.log(doTheMagic([a1, a2, a3]));
This works with an unknown number of arrays, each one of unknown length :
const arrays = [
[1, 2, 3, 4],
["a", "b", "c", "d", "e"],
["#", "#", "?"]
];
let output = [];
while (arrays.some(a => a.length)) { // While any of the arrays still has an element in it, keep going
for (let a of arrays) {
if (!a.length) continue;
output.push(a.shift()); // remove the first element of the array and add it to output
}
}
console.log(output)
This is my approach to achieve that, one for loop can make it. This will work if you don't know the number of arrays and array length as well.
function doTheMagic(arr){
let ans = [];
let maxLength = -1;
arr.forEach((tempArr)=>{
if(tempArr.length > maxLength){
maxLength = tempArr.length;
}
})
let l1=0,l2=0,l3=0;
for(let i=0;i<maxLength;i++){
arr.forEach((tempArr)=>{
if(tempArr[i]){
ans.push(tempArr[i]);
}
})
}
return ans;
}
let a1 = [1,2,3,4,5];
let a2 = ["🏯","🏜","🏭","🎢","🌠","🏗"];
let a3 = ['1','2','3','4','5'];
console.log(doTheMagic([a1,a2,a3]));
Not sure if this is the better, but how you can write code that handles any number of arrays passed in.
const weave = (...args) => // convert arguments to an array
args.reduce((res, arr, offset) => { // loop over the arrays
arr.forEach((v, i) => res[offset + i * args.length] = v) // loop over array and add items to their indexes
return res
}, []).filter(x => x !== undefined) // remove the unused indexes
const one = [1, 2, 3]
const two = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
const three = ['w', 'x', 'y', 'z']
const result = weave(one, two, three)
console.log(result)
const result2 = weave(one, two)
console.log(result2)
const result3 = weave(one, two, three, ['*', '&'])
console.log(result3)
var ar = ['a','a','a','b','e','e']
var charMap ={}
for(let char of ar){
charMap[char] = charMap[char] +1 || 1
}
const result = [];
for(let ch in charMap){
if(charMap[ch] %2 !== 0 ){
result.push(Object.keys(ch))
}
}
console.log(result);
The result should be like ['a','a','a','b'], but I am getting something else.
Please help me out.
Just use filter method by passing a callback provided function as argument.
var ar = ['a','a','a','b','e','e']
ar = ar.filter(function(item){
return ar.filter(elem => elem == item).length %2 == 1;
});
console.log(ar);
Another approach is to use filter method in combination with reduce.
var ar = ['a','a','a','b','e','e']
ar = ar.filter(function(item){
return ar.reduce((pre, current) => (current == item) ? ++pre : pre, 0) % 2 == 1;
});
console.log(ar);
You could take a Map and count the values in advance. Then filter the array by checking the count.
var array = ['a', 'a', 'a', 'b', 'e', 'e'],
result = array.filter(
Map.prototype.get,
array.reduce((m, v) => m.set(v, (m.get(v) || 2) - 1), new Map)
);
console.log(result);
UPDATE: I figured out the solution on my own. instead of doing the solutions below, a simpler solution is
CODE SOURCE
let trUp = (chord)=>{
let index= arr.indexOf(chord);
return arr.IndedOf(index) - 1;
}
You could use an array and look for the index and increment by adjusting by the length of the array with the reminder operator %.
function up(note) {
return notes[(notes.indexOf(note) + 1) % notes.length];
}
var notes = ['A', 'A#', 'B', 'C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#'];
console.log(up('C'));
Slightly longer version that would allow you to transpose single chords or an array of chords either up / down...
const chordMap = ['A','A#','B','C','C#','D','D#','E','F','F#','G','G#'];
Define some functions to move chords either up or down 1 and return the result
function chordUp(chord) {
let index = chordMap.indexOf(chord) + 1;
if (index >= chordMap.length) index = 0;
return chordMap[index];
}
function chordDown(chord) {
let index = chordMap.indexOf(chord) - 1;
if (index < 0) index = chordMap.length - 1;
return chordMap[index];
}
Then functions to transpose an entire array of chords up or down 1 and return the results as an array
function transposeUp(input) {
let output = [];
for (let i = 0; i < input.length; i++) {
let chord = input[i];
output.push(chordUp(chord));
}
return output;
}
function transposeDown(input) {
let output = [];
for (let i = 0; i < input.length; i++) {
let chord = input[i];
output.push(chordDown(chord));
}
return output;
}
Finally you can use it like so...
let chords = ['A', 'G#', 'B', 'C#', 'A#', 'G'];
let transposedUp = transposeUp(chords); // [ "A#", "A", "C", "D", "B", "G#" ];
let transposedDown = transposeDown(chords) // [ "G#", "G", "A#", "C", "A", "F#" ];