skip to Main Content

I need help with some logic in javascript.

I have one list of objects say:

const listA = [
  { name: 'John', visible: true },
  { name: 'Andy', visible: false },
  { name: 'Oliver', visible: true },
  { name: 'Freddy', visible: true },
];

And I want to sort listA based on another list of strings, say:

const listB = ['Oliver', 'John', 'Freddy'];

But there’s a catch, some of the items are missing in listB which are present in listA. In the above example ‘Andy’ is missing.

After applying the sorting logic, I would like to obtain the following output for the above scenario:

const listC = [
  { name: 'Oliver', visible: true },
  { name: 'Andy', visible: false },
  { name: 'John', visible: true },
  { name: 'Freddy', visible: true },
];

Note that since ‘Andy’ is missing from the listB, he should keep its previous order position.

I event tried ChatGPT4 with the same prompt like in this post but it wasn’t able to give me a working solution.. even after multiple attempts.

See below a starting point which is not working properly

const listA = [
  { name: 'John', visible: true },
  { name: 'Andy', visible: false },
  { name: 'Oliver', visible: true },
  { name: 'Freddy', visible: true },
];

const listB = ['Oliver', 'John', 'Freddy'];

function sortByList(arrayA, arrayB) {
  const foundInListB = arrayA
    .filter((item) => arrayB.includes(item.name))
    .sort((a, b) => arrayB.indexOf(a.name) - arrayB.indexOf(b.name));

  const notFoundInListB = arrayA.filter((item) => !arrayB.includes(item.name));

  return [...foundInListB, ...notFoundInListB];
}

// Result
const listC = sortByList(listA, listB);

// Append the sorted names to the HTML list
const result = document.getElementById('app');
listC.forEach((item) => {
  const listItem = document.createElement('li');
  listItem.textContent = item.name;
  result.appendChild(listItem);
});

2

Answers


  1. You can first create a new array. Then — for each name in the list — find the first object in the unsorted array that matches the name, pushing the object into the new array. Afterward, iterate the original unsorted array of objects and splice each one that wasn’t already found into the new array at its original index:

    Code in the TypeScript Playground

    function sortNames(unsorted, names) {
      const sorted = [];
      const found = new Set();
    
      for (const name of names) {
        const obj = unsorted.find((o) => o.name === name);
        if (obj) {
          found.add(obj);
          sorted.push(obj);
        }
      }
    
      for (const [index, obj] of unsorted.entries()) {
        if (!found.has(obj)) sorted.splice(index, 0, obj);
      }
    
      return sorted;
    }
    
    const listA = [
      { name: "John", visible: true },
      { name: "Andy", visible: false },
      { name: "Oliver", visible: true },
      { name: "Freddy", visible: true },
    ];
    
    const listB = ["Oliver", "John", "Freddy"];
    
    const listC = [
      { name: "Oliver", visible: true },
      { name: "Andy", visible: false },
      { name: "John", visible: true },
      { name: "Freddy", visible: true },
    ];
    
    const sorted = sortNames(listA, listB);
    console.log(sorted);
    
    const equal = JSON.stringify(sorted) === JSON.stringify(listC);
    console.log({ equal }); // true
    Login or Signup to reply.
  2. its my first answer here at stackoverflow

    const arr = [];
    const listC = [];
    
    listA.forEach((string, index) => {
        let found = false;
    
        for (let i = 0; i < listB.length; i++) {
            console.log(string, listB[i], i, index);
            if (string.name === listB[i]) {
                found = true;
                break;
            }
        }
    
        if (!found) {
            arr.push({ index, ob: listA[index] });
        }
    });
    
    console.log(arr);
    
    listB.forEach(name => {
        listC.push({ name, visibility: true });
    });
    
    arr.forEach(item => {
        listC.splice(item.index, 0, item.ob);
    });
    
    console.log(listC);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search