bmvr
bmvr

Reputation: 866

Sort in multi-dimensional arrays in javascript

I have a multi array object in javascript

[["A","F","A","H","F","F"],["F","A","A","F","F","H"]]

I want obtain the following using some sorting algorithm

[["A","A","A","H","A","F"],["F","F","F","F","F","H"]]

The letters that are not in "A" and "F" should stay in the same position of their arrays. Only "A" and "F" should be sorted.

Upvotes: 2

Views: 85

Answers (4)

Nina Scholz
Nina Scholz

Reputation: 386530

You could use a traditional approach with filtering the nonsortable items and sort the rest and splice the unsortable items to their original position.

function sort(array) {
    var solid = [],
        sortable = { A: true, F: true },
        i = array.length;

    while (i--) {
        sortable[array[i]] || solid.unshift({ index: i, value: array.splice(i, 1)[0] });
    }

    array.sort(function (a, b) {
        return a.localeCompare(b);
    });
    solid.forEach(function (a) {
        array.splice(a.index, 0, a.value);
    });
}

var array = [["A", "F", "A", "H", "F", "F"], ["F", "A", "A", "F", "F", "H"]],
    temp = array[0].concat(array[1]);

sort(temp);
array = [temp.slice(0, 6), temp.slice(6, 12)];
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 0

ngstschr
ngstschr

Reputation: 2319

    var myArrays = [["A","F","A","H","F","F"],["F","A","A","F","F","H"]];
    var lengths = [];
    var tempArray = [];
    var sortArray = [];
    var noSortArray = [];
    myArrays.forEach(function(arr) {
        lengths.push(arr.length);
        tempArray = tempArray.concat(arr);
    });
    tempArray.forEach(function(item, index) {
        if (item === 'H') {
            noSortArray.push({index: index, item: item});
        } else {
            sortArray.push(item);
        }
    });
    sortArray.sort();
    noSortArray.forEach(function(item) {
        sortArray.splice(item.index, 0, item.item);
    });

    var position = 0;
    var theLength = 0; 
    myArrays = [];
    lengths.forEach(function(aLength) {
        theLength += aLength;
        myArrays.push(sortArray.slice(position, theLength));
        position += aLength;
        console.log(position);
    });

    console.log(myArrays);
    

Upvotes: 0

Nenad Vracar
Nenad Vracar

Reputation: 122027

You could flatten your array, sort it so that every A comes before F and then slice it again to match the structure of original data.

var data = [["A","F","A","H","F","F"],["F","A","A","F","F","H"]]

function custom_sort(data) {
  var sort = [].concat(...data.slice()), r = []
  sort.forEach(function(e, i) {
    if (e == 'A') {
      var fi = sort.indexOf('F')
      if (fi < i)(sort[fi] = 'A', sort[i] = 'F')
    }
  })

  data.forEach(e => r.push(sort.splice(0, e.length)))
  return r
}

console.log(JSON.stringify(custom_sort(data)))
console.log(JSON.stringify(custom_sort( [["F","F","A","H","F"],["F", "Z", "I", "A","A","A","F","H", "A"]])))

Upvotes: 1

Sagar V
Sagar V

Reputation: 12478

Check this. Just run this code.

function sortIt(a){
  var i=0,j=0;
  while(i<a.length){
     j=i;
     while(j<a.length){
       if((a[i]=="F" || a[i]=="A") && (a[j]=="F" || a[j]=="A") && a[i].charCodeAt(0)>a[j].charCodeAt(0)){
          temp=a[i];
          a[i]=a[j];
		  a[j]=temp;
	   }
	   j++;
	}
    i++;
  }
  return a;
}

function splitUp(a){
   var b=[],i=0;
   while(i<a.length){
     b.push(sortIt(a[i]));
     i++;
   }
   return b;
}

//test

var c=[['A','F','F','H','B','A','A','F','Z','X'],['F','A','A','F','F']];
console.log("Before Sorting\n");
console.log(c);
c = splitUp(c);
console.log("After sorting");
console.log(c);

Upvotes: 0

Related Questions