javascript - filtering an array of strings - Stack Overflow

I need to filter an array and I am totally drawing a blank on how to do so.I need to filter out the lar

I need to filter an array and I am totally drawing a blank on how to do so.

I need to filter out the largest numbers. A number can be deemed larger when the first number is 'XXXX' and the second is 'XXXX-1', then the second number is larger. Or it can be deemed larger if the first number is 'XXXX-1' and the second is 'XXXX-2', then the second is largest.

In the case that the number has no version thats larger, in the example below lets look at '2234'. There is no '2234-1', so thus, '2234' is the largest of its kind and should be removed.

So given this array (of strings) as an example:

['7851', '7851-2', '7851-1', '2234', '2235', '2235-1']

I would expect this result:

['7851', '7851-1', '2235']

I need to filter an array and I am totally drawing a blank on how to do so.

I need to filter out the largest numbers. A number can be deemed larger when the first number is 'XXXX' and the second is 'XXXX-1', then the second number is larger. Or it can be deemed larger if the first number is 'XXXX-1' and the second is 'XXXX-2', then the second is largest.

In the case that the number has no version thats larger, in the example below lets look at '2234'. There is no '2234-1', so thus, '2234' is the largest of its kind and should be removed.

So given this array (of strings) as an example:

['7851', '7851-2', '7851-1', '2234', '2235', '2235-1']

I would expect this result:

['7851', '7851-1', '2235']
Share Improve this question edited Feb 24, 2017 at 9:50 gyre 16.8k4 gold badges40 silver badges47 bronze badges asked Feb 24, 2017 at 9:03 Houssem ChlegouHoussem Chlegou 1491 silver badge13 bronze badges 0
Add a ment  | 

4 Answers 4

Reset to default 5

You could group the items and sort it later, then pop the last and filter the original array with a look up for the saved value.

var array = ['7851', '7851-2', '7851-1', '2234', '2235', '2235-1'],
    result = function (array) {
        var groups = Object.create(null);

        array.forEach(function (a) {
            var key = a.split('-')[0];
            groups[key] = groups[key] || [];
            groups[key].push(a);
        });

        Object.keys(groups).forEach(function (k) {
            groups[k].sort().pop();
        });

        return array.filter(function (a) {
            return groups[a.split('-')[0]].some(function (b) { return a === b; });
        });
    }(array);

console.log(result);

A bination of reduce and map would do the job in one go:

let a = ["7851", "7851-2", "7851-1", "2234", "2235", "2235-1"];
let b = [...a.reduce((a, b) => {
  let s = b.split("-");
  a.set(s[0], (!a.has(s[0]) ? [(s[1] || 0)] : a.get(s[0]).concat((s[1] || 0))));
  return a;
}, new Map()).entries()].map(k => {
  k[1].sort((a, b) => b < a).pop();
  if (k[1].length === 0) return;
  return k[1].map(f => k[0] + (f > 0 ? "-" + f : ""))
}).filter(v => v).reduce((a, b) => a.concat(b), []);
console.log(b);

Using JavaScript you can try the code below:

var numbers = ["7851", "7851-2", "7851-1", "2234", "2235", "2235-1"];
var arr = [];
for (var i = 0; i < numbers.length; i++)
{
    // The first part of the number defines the hash key
    var hash_key = numbers[i].split("-")[0];
    if (arr[hash_key] === undefined)
    {
        arr[hash_key] = [];
    }
    arr[hash_key][arr[hash_key].length] = numbers[i];
}

// sort each array - 
// then access all elements but the last and populate numbers array 
var numbers = [];
var j = 0;
for (var k in arr) {            
    arr[k].sort();
    for (var i = 0; i < arr[k].length - 1; i++) {
        numbers[j] = arr[k][i];
        j++;                
    }
}

console.log(numbers);

All the current solutions assume that the numbers will be XXXX-Y where Y is always a number between 0 and 9 (maybe it is the requirement, but it is not clear in the question). In this case, we are working with Strings, so 1234-15 will be lower than 1234-7. It is needed to sort the Arraysin a numeric way. If we use the next Array with the current solutions on the page, this will be the results:

var array = ["14670-20", "7851", "7851-2", "14670-10", "7851-1", "2234", "2235", "2235-1", "14670-7"];

// ["14670-20", "7851", "14670-10", "7851-1", "2235"]
// ["14670-10", "14670-20", "7851", "7851-1", "2235"]
// ["2235", "7851", "7851-1", "14670-10", "14670-20"]

The number 14670-7 has been dropped because, as String, it is bigger than 14670-10 and 14670-20.

Here you have a solution that orders the Array first, and next reduce the values to get the lower ones (this solution changes the order of the original Array)

var array = ["14670-20", "7851", "7851-2", "14670-10", "7851-1", "2234", "2235", "2235-1", "14670-7"];

function getFilteredArray (array) {
    var reg = /^(\d+)\-?(\d*)$/;	
    var current = "";
    var sort = function (a, b) {
        var ra = a.match(reg), rb = b.match(reg);
        if (ra[1] === rb[1]) { return (+ra[2]) - (+rb[2]); }
        return (+ra[1]) - (+rb[1]);
    }
    return array.sort(sort).reduce(function (bundle, item, index) {
        var number = item.split("-")[0];
        bundle.splice((current !== number) ? -1 : bundle.length, 1, item);
        current = number;
        return bundle;
    }, []).slice(0, -1); 
}

console.log( getFilteredArray(array) );

This another solution is a little longer but it keeps the order of the original Array:

var array = ["14670-20", "7851", "7851-2", "14670-10", "7851-1", "2234", "2235", "2235-1", "14670-7"];

function getFilteredArray (array) {
    var reg = /^(\d+)\-?(\d*)$/;
    var sort = function (a, b) {
        var ra = a.match(reg), rb = b.match(reg);
        if (ra[1] === rb[1]) { return (+ra[2]) - (+rb[2]); }
        return (+ra[1]) - (+rb[1]);
    }
    var objs = array.reduce(function (bundle, item) {
        var number = item.split("-")[0];
        bundle[number] = bundle[number] || [];
        bundle[number].push(item);
        return bundle;
    }, {});
    for (var prop in objs) {
        var last = objs[prop].sort(sort).pop();
        array.splice(array.indexOf(last), 1);
    }
    return array;  
}

console.log( getFilteredArray(array) );

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745300777a4621421.html

相关推荐

  • javascript - filtering an array of strings - Stack Overflow

    I need to filter an array and I am totally drawing a blank on how to do so.I need to filter out the lar

    12小时前
    30

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信