Home > Net >  How to filter an array of objects storing only once for each matched item
How to filter an array of objects storing only once for each matched item

Time:06-28

I'm working with Javascript, and have the following array of objects:

const offersStep = [
     {a: 1, price: 67.10},
     {a: 3, price: 88.20},
     {a: 5, price: 88.20}, 
     {a: 7, price: 57.10},
     {a: 13, price: 57.10},
     {a: 15, price: 57.10},
     {a: 29, price: 57.10},
     {a: 30, price: 57.10},
]

What and How i have to do, in order to store in a new array, those objects, ignoring it those who the prop price has a value who is already stored on the new array?

Expected output:

offers = [
  {a: 1, price: 67.10},
  {a: 3, price: 88.20},
  {a: 7, price: 57.10}
]

CodePudding user response:

You can store the objects in a Map keyed off its price. After you have stored unique prices, spread the values() iterator of the Map into a new array to get your result.

const offersStep = [
     {a: 1, price: 67.10},
     {a: 3, price: 88.20},
     {a: 5, price: 88.20}, 
     {a: 7, price: 57.10},
     {a: 13, price: 57.10},
     {a: 15, price: 57.10},
     {a: 29, price: 57.10},
     {a: 30, price: 57.10},
];

function filterOffers(offers) {
  let offersByPrice = new Map();
  for (let offer of offers) {
    if (!offersByPrice.has(offer.price)) {
      // Store the offer
      offersByPrice.set(offer.price, offer);
    }
  }
  
  return [...offersByPrice.values()];
}

console.log(filterOffers(offersStep));

CodePudding user response:

Idea

Filter the original array, keeping tabs on the prices encountered so far by means of a set.

Code

const offersStep = [
     {a: 1, price: 67.10},
     {a: 3, price: 88.20},
     {a: 5, price: 88.20}, 
     {a: 7, price: 57.10},
     {a: 13, price: 57.10},
     {a: 15, price: 57.10},
     {a: 29, price: 57.10},
     {a: 30, price: 57.10}
];

let offer
  , nset_prices = new Set() 
  ;

offer = offersStep.filter ( po_item => {
            let b_ok = !nset_prices.has(po_item.price)
              ;

            if (b_ok) {
                nset_prices.add(po_item.price)
            }
            return b_ok;
        });

console.log(offer);

CodePudding user response:

Let me if the code works for you!

const offersStep = [
  { a: 1, price: 67.1 },
  { a: 3, price: 88.2 },
  { a: 5, price: 88.2 },
  { a: 7, price: 57.1 },
  { a: 13, price: 57.1 },
  { a: 15, price: 57.1 },
  { a: 29, price: 57.1 },
  { a: 30, price: 57.1 },
];

let tempOffers = {};

offersStep.forEach((eachObj) => {
  const { price } = eachObj;
  if (!tempOffers[price]) {
    tempOffers[price] = eachObj;
  }
});

const offers = Object.values(tempOffers);

console.log("offers are", offers);

CodePudding user response:

Use iteration to determine if previously saved prices match the current object being iterated.

const offersStep = [
     {a: 1, price: 67.10},
     {a: 3, price: 88.20},
     {a: 5, price: 88.20}, 
     {a: 7, price: 57.10},
     {a: 13, price: 57.10},
     {a: 15, price: 57.10},
     {a: 29, price: 57.10},
     {a: 30, price: 57.10},
]

// Vars to store previously recorded prices.
var storedPrices = [];

// Var to store unique offersStep.
var uniqueOffersStep = [];

// Iterates through each of the offersStep array objects.
offersStep.forEach (function(value) {
  // Sets a boolean to false .. used later to determine if the current object is added to the unique array.
  var isSkip = false;
  
  // Iterates through each of the storedPrices array.
  storedPrices.forEach (function(spvalue) {
    // If the current objects price matches one of the storedPrices then it sets the skip flag to true.
    if (value.price == spvalue) {
      isSkip = true;
    }
  })
  // Adds the current objects price to the storedPrices array.
  storedPrices.push(value.price);
  
  // Check if the skip flag is still false after checking stored prices and adds the object to the uniqueOffers variable.
  if (isSkip == false) {
    uniqueOffersStep.push(value);
  }
})

// Outputs the final var to console.
console.log(uniqueOffersStep);

As this relies on multiple layers of iteration it would be fairly resource heavy with larger data sets.

Hope this helps.

CodePudding user response:

const newArray = offersStep.reduce((acc,curr) => {
    if(acc.find(item => item.a === curr.a)) {
        return acc
    }
    return acc.concat(curr)
},[])

CodePudding user response:

You could filter with a set of prices.

const
    filterWithSet = s => ({ price }) => !s.has(price) && s.add(price),
    offersStep = [{ a: 1, price: 67.10 }, { a: 3, price: 88.20 }, { a: 5, price: 88.20 },  { a: 7, price: 57.10 }, { a: 13, price: 57.10 }, { a: 15, price: 57.10 }, { a: 29, price: 57.10 }, { a: 30, price: 57.10 }],
    result = offersStep.filter(filterWithSet(new Set));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

CodePudding user response:

Using reduce, find, and ternary operator, to iterate given array, check if item price is existing, and append to a collection array if not found:

const offersStep = [
     {a: 1, price: 67.10},
     {a: 3, price: 88.20},
     {a: 5, price: 88.20}, 
     {a: 7, price: 57.10},
     {a: 13, price: 57.10},
     {a: 15, price: 57.10},
     {a: 29, price: 57.10},
     {a: 30, price: 57.10},
]

const offers = offersStep.reduce(
  (arr, item) => // collection array, and iteration item
     // check collection array for item price
     (arr.find(item2 => item2.price === item.price))
         ? arr // item price exists so return array unchanged
         : [...arr, item], // return array with item appended
  [] // initial collection array
);
console.log(offers);

CodePudding user response:

Using Array.Some

// data source
const offersStep = [
     {a: 1, price: 67.10},
     {a: 3, price: 88.20},
     {a: 5, price: 88.20}, 
     {a: 7, price: 57.10},
     {a: 13, price: 57.10},
     {a: 15, price: 57.10},
     {a: 29, price: 57.10},
     {a: 30, price: 57.10},
];

// this is the array to store new objects after dupliacte check
const offers =[]; 

offersStep.forEach(
     (d,i)=>{
     //push the first object from the array of objects
         (i==0)?offers.push({a:d.a,price:d.price}):
    //for the subsequent index, check offers if there exists at least one  
    // value for price that matches the current price from offersStep.price
    // if yes, don't push, else push
             offers.some(x=>x.price==d.price)===false?offers.push({a:d.a,price:d.price}):null 
     }
     );
console.log(offers);

  • Related