2

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.

6
  • are you trying to sort the base list and inner lists or just the inner lists inside the base list? Commented Feb 9, 2017 at 10:13
  • multi-dimensional part seems irrelevant Commented Feb 9, 2017 at 10:15
  • 1
    concat the 2 arrays; sort it with custom sort that leaves non a/f in place; split back into 2 arrays Commented Feb 9, 2017 at 10:18
  • is it a positional thing? comparing the array index-to-index to swap the items? are A and F the only two letter you'll ever want to swap around? Commented Feb 9, 2017 at 10:19
  • Ok guys, this might be a little confusing A = remaining vacations from last year, F = vacations from curr year, H = holidays/weekends. when someone is scheduling their vacations my algorithm must be intelligent enough to first set A and then F, holidays must be in the same place, imagine my arrays as days of month, I just didnt paste the entire 31 positions. The base list it's the year and the inner are the months Commented Feb 9, 2017 at 10:33

4 Answers 4

1

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"]])))

Sign up to request clarification or add additional context in comments.

1 Comment

@BrunoRodrigues If it works perfectly then maybe upvote/accept it?
0

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);

Comments

0

    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);
    

Comments

0

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; }

1 Comment

You're solution it's almost perfect, if you concat the array and then split it again. Because the A must always be first. Anyway it helped me, thx.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.