0

I have an array, each subarray of which contains different positions in different order:

[
  ["apple(2)", "banana(5)"],
  ["peach(3)", "banana(1)"],
  ["apple(1)"]
]

I need to sort it on JavaScript (ES6) and i expect to get an array like this:

[
  ["apple(2)", "banana(5)", "peach(0)"],
  ["apple(0)", "banana(1)", "peach(3)"],
  ["apple(1)", "banana(0)", "peach(0)"]
]

Order of each subarray should be the same. If subarray don't have some position, i need to add it with 0 value. Can i using something like map() or sort() function or need to compare it manually?

9
  • 1
    Is there a list of possible values? Or does it have to be calculated from the array? Commented Nov 3, 2020 at 19:18
  • Please explain how you got the output format. Commented Nov 3, 2020 at 19:19
  • @epascarello i need compare and sort only words, not a numbers, numbers is unique Commented Nov 3, 2020 at 19:21
  • 1
    I know.... but is the list of words known? The complexity of the answer depends on that. Commented Nov 3, 2020 at 19:22
  • 1
    So it is complicated. You need to first loop over all the arrays and get the possible words. After that you need to reloop and add the missing words and sort. A bunch of ways to do it. Commented Nov 3, 2020 at 19:27

3 Answers 3

1

Here is functional programming approach, using a Map and reduce:

const data = [['apple(2)', 'banana(5)'],['peach(3)', 'banana(1)'],['apple(1)'],];

// Create a Map with default values for each name, i.e. with "(0)":
let names = new Map(data.flat().map(item => [item.replace(/\d+/, ""), item.replace(/\d+/, "0")]));
let result = data.map(row =>
    [...row.reduce((map, item) => 
        map.set(item.replace(/\d+/, ""), item), // Overwrite default
        new Map(names) // Start with clone of original Map
    ).values()]
);
console.log(result);

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

2 Comments

I just changed .flat() to .reduce((a, b) => a.concat(b), []) because unfortunately i need to support EdgeHTML (Edge 12+).
If you don't have support for data.flat(), then [].concat(...data) can be an alternative.
1

You have to loop over to get the keys used. You then have to loop over a second time to get the fill in the missing keys. There are many ways of doing it, this is one.

var data = [
  ["apple(2)", "banana(5)"],
  ["peach(3)", "banana(1)"],
  ["apple(1)"]
];

// match string and number
var re = /([^(]+)\((\d+)\)/;

// Loop over and find all of the keys
var grouped = data.reduce((info, subset, index) => {
  subset.forEach(item => {
    // find the key and count
    var parts = item.match(re);
    // have we seen this key?
    if (!info[parts[1]]) {
      // if not create an array
      info[parts[1]] = Array(data.length).fill(0);
    }
    // set the key index with the count
    info[parts[1]][index] = parts[2];
  })
  return info;
}, {});

// loop over the groups and fill in the set
Object.entries(grouped).forEach(([key, counts], colIndex) => {
  counts
    .forEach((cnt, rowIndex) => {
      data[rowIndex][colIndex] = `${key}(${cnt})`;
    })
});

console.log(data);

Comments

1

First get the unique words. Then traverse array of arrays to check if the word is present or not. If it is not present then make the word according to your condition and if present then put the original word to the tmp array. At last sort it for each iteration. By the way, I used regex replace method to get the word.

const data = [
  ['apple(2)', 'banana(5)'],
  ['peach(3)', 'banana(1)'],
  ['apple(1)'],
];
const words = [...new Set(data.flat().map((x) => x.replace(/[^a-z]/gi, '')))];
const ret = data.map((x) => {
  const tmp = [];
  const newX = x.map((y) => y.replace(/[^a-z]/gi, ''));
  for (let i = 0, l = words.length; i < l; i += 1) {
    if (newX.includes(words[i])) tmp.push(x.shift());
    else tmp.push(`${words[i]}(0)`);
  }
  return tmp.sort();
});
console.log(ret);

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.