0
records = [
        {
            name: "Alpha",
            set: 5,
            weight: 185
        },      
        {
            name: "Alpha",
            set: 5,
            weight: 350
        },        
        {
            name: "Bravo",
            set: 5,
            weight: 185
        },        
        {
            name: "Charlie",
            set: 5,
            weight: 185
        },         
        {
            name: "Delta",
            set: 5,
            weight: 185
        }
]

I have a JSON array of multiple records and I need to filter these records by name and weight. So for example, since there are two "Alpha" records, I need to only pull in the one with the highest weight (which would be the second record). I have no idea how to filter and rebuild this array with only the desired results.

I need to keep the original array intact as I'll be displaying ALL in a table, but I need to build a secondary array with only the objects with the greatest value, by name.

1

4 Answers 4

4

You can use lodash 4+ for this.

var sortedArray = _.orderBy(records, ['weight'], ['desc']);

This will sort the array by weight. Then , _.uniqBy(sortedArray,'name')

This will return the final array.

var records = [
        {
            name: "Alpha",
            set: 5,
            weight: 185
        },      
        {
            name: "Alpha",
            set: 5,
            weight: 350
        },        
        {
            name: "Bravo",
            set: 5,
            weight: 185
        },        
        {
            name: "Charlie",
            set: 5,
            weight: 185
        },         
        {
            name: "Delta",
            set: 5,
            weight: 185
        }
]

var sortedArray = _.orderBy(records, ['weight'], ['desc'])

_.uniqBy(sortedArray,'name')
Sign up to request clarification or add additional context in comments.

Comments

3

I recommend a functional programming approach:

var newRecords = records
    .filter(function(record) { 
        return records.find(function(innerRecord) {
            return innerRecord.name === record.name && innerRecord.weight > record.weight; }) === undefined;
     });

In this example, you return only records where you cannot find a record sharing the same name but with a larger weight. Also, your newly re-built array is stored in newRecords, leaving your original array intact.

Comments

2

I recommend you start using lodash and dont spend time to create your own functions. For example, to sort your array by name you should write the following code:

    var records = [
        {
            name: "Alpha",
            set: 5,
            weight: 185
        },      
        {
            name: "Alpha",
            set: 5,
            weight: 350
        },        
        {
            name: "Bravo",
            set: 5,
            weight: 185
        },        
        {
            name: "Charlie",
            set: 5,
            weight: 185
        },         
        {
            name: "Delta",
            set: 5,
            weight: 185
        }
];
var sorted = _.sortBy(records, ['name']);

And second case, to filter by name and weight

var filtered = _.filter(records, [ 'name': 'Alpha', 'weight': 350 ]);

4 Comments

Does this also filter out multiple of the same type? As this is something OP wants
And code will look like _.filter(records, [name:"Alpha", weight: 350]
It should be included in the answer, as of now your solution only solves the sorting.
Updated the solution
2

This first sorts the items in name order and weight order and then filter out all but the first of each item.

var records = [{
    name: "Alpha",
    set: 5,
    weight: 185
  },
  {
    name: "Alpha",
    set: 5,
    weight: 350
  },
  {
    name: "Bravo",
    set: 5,
    weight: 185
  },
  {
    name: "Charlie",
    set: 5,
    weight: 185
  },
  {
    name: "Charlie",
    set: 5,
    weight: 200
  },
  {
    name: "Delta",
    set: 5,
    weight: 185
  }
]

console.log(
  records.sort((a, b) => {
    if (a.name === b.name) {
      return a.weight >= b.weight ? -1 : 1
    }
    return a.name > b.name ? 1 : -1
  })
  .filter((rec, i, arr) => {
    if (i === 0) return true
    return rec.name !== arr[i - 1].name
  })
)

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.