0

How do I sort an array as close as possible to a target array as possible.

For example:

The array can only contain a maximum of 4 elements:

['javascript', 'html', 'css', 'result'];

But in cases where it isn't, the sorting should be as follows:

['css', 'result', 'html']; sorted to ['html', 'css', 'result'];

['result', 'css', 'javascript']; sorted to ['javascript', 'css', 'result'];

The criteria is to get it as close to ['javascript', 'html', 'css', 'result']; as possible, and where a particular element does not exist, skip it.

My current code seems to do it incorrectly, I've included it below:

function setFiddleTabsArray(updatedFiddleTabs) {
  if (updatedFiddleTabs.length === 4) {
    updatedFiddleTabs = ['javascript', 'html', 'css', 'result'];
  } else {
    const correctFiddleTabsOrder = ['javascript', 'html', 'css', 'result'];
    const fiddleTabsSorter = (a, b) => {
      if (correctFiddleTabsOrder.includes(a)) {
        return -1;
      }
      if (correctFiddleTabsOrder.includes(b)) {
        return 1;
      }
      return 0;
    };
    updatedFiddleTabs.sort(fiddleTabsSorter);
    return updatedFiddleTabs;
  }
  return updatedFiddleTabs;
}

const test1 = setFiddleTabsArray(['css', 'html', 'result']);
console.log(test1);

How do I fix it?

4
  • 1
    What is the exact criteria for sorting? Commented Apr 1, 2021 at 15:12
  • It's hard to make sense from the examples. Why, in the example with the array that includes "result" twice, does the result end up with "html" instead? Why not "javascript"? Commented Apr 1, 2021 at 15:13
  • 2
    includes is wrong, you should be sorting based on index Commented Apr 1, 2021 at 15:15
  • Sorry I've fixed it. The criteria is to get it as close to ['javascript', 'html', 'css', 'result']; as possible, and where a particular element does not exist, skip it. Commented Apr 1, 2021 at 15:16

3 Answers 3

4

You are always going to get 1 since it is always in the array. You need to sort based on the index of the match

function setFiddleTabsArray(updatedFiddleTabs) {
  if (updatedFiddleTabs.length === 4) {
    updatedFiddleTabs = ['javascript', 'html', 'css', 'result'];
  } else {
    const correctFiddleTabsOrder = ['javascript', 'html', 'css', 'result'];
    const fiddleTabsSorter = (a, b) => {
      return correctFiddleTabsOrder.indexOf(a) - correctFiddleTabsOrder.indexOf(b);
    };
    updatedFiddleTabs.sort(fiddleTabsSorter);
    return updatedFiddleTabs;
  }
  return updatedFiddleTabs;
}

const test1 = setFiddleTabsArray(['css', 'html', 'result']);
console.log(test1);

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

1 Comment

Thanks this fixes it. I really appreciate it!
1

An alternative is to extract the sort ranking to a separate object and sort with the following logic:

const sortRanking = {
  javascript: 0,
  html: 1,
  css: 2,
  result: 3,
};

const setFiddleTabsArray = (updatedFiddleTabs) =>
  updatedFiddleTabs.sort((a, b) => {
    if (sortRanking[a] > sortRanking[b]) return 1;
    if (sortRanking[a] < sortRanking[b]) return -1;
    return 0;
  });

const test1 = setFiddleTabsArray(["css", "html", "result"]);
console.log(test1);

This makes it very explicit and easy to follow imo

Comments

1

If you are always sure that nothing besides 'javascript', 'html', 'css', 'result' will ever be in the array, I would use the filter function.

function setFiddleTabsArray(updatedFiddleTabs) {
  if (updatedFiddleTabs.length === 4) {
      return ['javascript', 'html', 'css', 'result'];
  } else {
    const correctFiddleTabsOrder = ['javascript', 'html', 'css', 'result'];
    let result = correctFiddleTabsOrder.filter(element => updatedFiddleTabs.includes(element))
    return result;
  }
}

const test1 = setFiddleTabsArray(['css', 'html', 'result']);
console.log(test1);

Comments

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.