4

I have an array of strings like this:

const strings = [
  "author:app:1.0.0",
  "author:app:1.0.1",
  "author:app2:1.0.0",
  "author:app2:1.0.2",
  "author:app3:1.0.1"
];

And I want to filter them so that only the ones that have the latest versions for the given "author:name" are left, thus removing ones that are not the latest (i.e. the "1.0.1" ones).

My expected result is this:

const filteredStrings = [
  "author:app:1.0.1",
  "author:app2:1.0.2",
  "author:app3:1.0.1"
];

Any way to do this simply?

ldtcoop
  • 680
  • 4
  • 14
Asineth
  • 41
  • 2
  • 4
    Sorting means ordering, you're asking about filtering. – Barmar Mar 16 '20 at 22:02
  • 1
    Help us help you - please share the result you expect to get – Mureinik Mar 16 '20 at 22:02
  • 2
    Make an object whose keys are the `author:name` strings. Loop through the array, checking whether the current version string is higher than the one already in the object for that key. If it is, replace the value. When you're done you'll have the highest version for each key. – Barmar Mar 16 '20 at 22:03
  • 1
    I updated my post, tried to make it more clear. – Asineth Mar 16 '20 at 22:08

4 Answers4

1

You can do it with two loops first one find new ones second one check which is bigger

const strings = [
  "author:app:1.0.0",
  "author:app:1.0.1",
  "author:app2:1.0.0",
  "author:app2:1.0.2",
  "author:app3:1.0.1"
];
filteredones = [];
strings.forEach(element => {
  var arr = element.split(":");
  var isnew = true;
  var found = filteredones.find(function(element2) {
    var x = element2.split(":");
    return x[1] == arr[1] && x[0] == arr[0]
  });
  if (found == undefined) {
    filteredones.push(element);
  }
});
for (var i = 0; i < filteredones.length; i++) {
  element = filteredones[i];
  var arr = element.split(":");
  var isnew = true;
  var found = strings.find(function(element2) {
    var x = element2.split(":");
    return x[1] == arr[1] && x[0] == arr[0] && x[2] > arr[2]
  });
  if (found != undefined) {
    filteredones[i] = found;
  }
};

console.log(filteredones);
Zze
  • 18,229
  • 13
  • 85
  • 118
mr. pc_coder
  • 16,412
  • 3
  • 32
  • 54
  • `x[2]> arr[2]` is a simplistic way of comparing versions, won't work all the time, for instance v1.11 vs v1.2. Also, you are declaring `isnew` but isn't using. – ariel Mar 17 '20 at 06:30
0

you can check the value in the last index of the string in each of the elements of the array and if they qualify as a latest one put it to a new array.

danuja
  • 36
  • 4
0

Build an object with keys as app name.
getValue method is calculate the version value so that to compare.
Update object value, when you see the version is recent (value is big).

const strings = [
  "author:app:1.0.0",
  "author:app:1.0.1",
  "author:app2:1.0.0",
  "author:app2:1.0.2",
  "author:app3:1.0.1"
];

const filter = data => {
  const res = {};
  const getValue = item =>
    item
      .split(":")[2]
      .split(".")
      .reduceRight((acc, curr, i) => acc + curr * Math.pow(10, i), 0);
  data.forEach(item => {
    const app = item
      .split(":")
      .slice(0, 2)
      .join(":");
    if (!res[app] || (app in res && getValue(item) > getValue(res[app]))) {
      res[app] = item;
    }
  });
  return Object.values(res);
};

console.log(filter(strings));
Siva K V
  • 10,561
  • 2
  • 16
  • 29
  • Instead of `>` should be `<`, it's keeping the smallest numbers. Also your code don't work if different authors have same app name. Also on it v1.11 > v2.0 – ariel Mar 17 '20 at 05:29
  • @ariel, Good catch. I fixed both the issues. Thank you :) – Siva K V Mar 17 '20 at 06:25
0

You can use an object to store the key/version pairs, and convert to appropriate output on the end. The version comparison can be any of those found here: How to compare software version number using js? (only number)

result = {};
for (var s of input) {
  // parts = ["author", "appname", "version"]
  var parts = s.split(":");
  var i = parts[0] + ":" + parts[1];
  if (!result[i] || compareVersion(parts[2], result[i]))
    // If not present or version is greater
    result[i] = parts[2]; // Add to result
}
result = Object.keys(result).map(k => k + ":" + result[k])

Working demo: https://codepen.io/bortao/pen/LYVmagK

ariel
  • 15,620
  • 12
  • 61
  • 73