0

I want to rearrange the sentences so that each sentence is a prerequisites for the next sentence and here is what I have and it works fine:

const sentences = [
    "he has eaten a pizza at the party last night",
    "he has eaten a pizza",
    "he has eaten a pizza at the party",
]

function sessionCardsSort(arr) {
    arr = arr.map(part => part.split(' ')).sort((a, b) => a.length - b.length);
    function sortBy(list, main) {
        return list.sort((a, b) => {
            let count1 = 0, count2 = 0;
            a.forEach(part => { if(main.includes(part)) { count1++ } });
            b.forEach(part => { if(main.includes(part)) { count2++ } });
            return count1 - count2;
        });
    }
    return sortBy(arr, arr[arr.length - 1]).map(part => part.join(' '));
}

console.log(sessionCardsSort(sentences));

As you see I used a simple array named sentences as data structure to work with, but what if we want to use the same data of sentences array with new structure like this:

const sentences = [
    { reference: ['he has eaten a pizza at the party', 'last night'] }
    { reference: ['"he has', 'eaten a pizza'] },
    { reference: ['he', 'has', 'eaten a pizza at the party'] },
]

So the issue is I want to implement the exact same function this time for array of objects not just a simple array!

Here is desired result (only using the exact above function):

const sentences = [
        { reference: ['"he has', 'eaten a pizza'] },
        { reference: ['he', 'has', 'eaten a pizza at the party'] },
        { reference: ['he has eaten a pizza at the party', 'last night'] }
]

Note: In the second data structure joining elements inside each reference will give you the same sentence as the first example, for instance :

{ reference: ['he has eaten a pizza at the party', 'last night'] }  

"he has eaten a pizza at the party last night"

Note: Please note that I want to implement the exact same function

Sara Ree
  • 3,417
  • 12
  • 48

1 Answers1

0

Since the words of each sentence are either a strict subset of another sentence in the set, or the sentence is the largest one, it looks like it'd be a lot easier to just check the strings' overall length instead.

Give each sentence a length property (which is the length of the joined string), and then sort the resulting array of objects by that length, and finally remove the added length property.

const sentences = [
  { reference: ['"he has', 'eaten a pizza'] },
  { reference: ['he', 'has', 'eaten a pizza at the party'] },
  { reference: ['he has eaten a pizza at the party', 'last night'] }
];

function sessionCardsSort(sentences) {
  const sentencesWithLength = sentences.map(
    ({ reference }) => ({ reference, length: reference.join(' ') })
  );
  return sentencesWithLength
    .sort((a, b) => a.length - b.length)
    .map(({ reference }) => ({ reference }));
}

console.log(sessionCardsSort(sentences));

Or calculate the length each time inside the callback - more work (which could be a problem when dealing with huge datasets), but less code.

const sentences = [
  { reference: ['"he has', 'eaten a pizza'] },
  { reference: ['he', 'has', 'eaten a pizza at the party'] },
  { reference: ['he has eaten a pizza at the party', 'last night'] }
];

const toLength = arr => arr.reference.join(' ').length;
const sessionCardsSort = (sentences) => sentences
  .sort((a, b) => toLength(a) - toLength(b));
console.log(sessionCardsSort(sentences));

It doesn't look necessary given the input in the question, but if you really need to count words individually, then use a function with similar logic to your current sortBy to count up the number of included words.

const sentences = [
  { reference: ['"he has', 'eaten a pizza'] },
  { reference: ['he', 'has', 'eaten a pizza at the party'] },
  { reference: ['he has eaten a pizza at the party', 'last night'] }
];

const toLength = obj => obj.reference.join(' ');
const toWordsIncluded = (obj, mainWords) => obj.reference
  .join(' ')
  .split(' ')
  .reduce((subtotal, word) => subtotal + mainWords.includes(word), 0)
  
const sessionCardsSort = (sentences) => {
  const sorted = sentences
    .sort((a, b) => toLength(a) - toLength(b));
  const mainWords = sorted[sorted.length - 1].reference.join(' ').split(' ');
  return sorted
    .sort((a, b) => toWordsIncluded(a, mainWords) - toWordsIncluded(b, mainWords));
};
console.log(sessionCardsSort(sentences));
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320