2

I have a list of String with duplicate entries , So i want to remove them irrespective of Case

let duplicates = ['Hello', 'Hi', 'hello'];
let uniques = _.methodName(duplicates);

// output should be
['hello','Hi'] OR ['Hello','Hi']
Ankesh Pandey
  • 105
  • 1
  • 13
  • Does this have to be lodash? Here's a vanilla js question: [javascript unique string array case insensitive but keep one case sensitive result](https://stackoverflow.com/questions/48731396) – adiga Dec 26 '19 at 09:43

5 Answers5

1

One solution that avoids the need for a dependancy like lodash would be the following "vanilla js" approach:

let duplicates = ['Hello', 'Hi', 'hello'];

/* Pluck the values of the object mapping to an array */
let uniques = Object.values(
  /* "Reduce" input array to an object mapping */
  duplicates.reduce((obj, str) =>     
  /* Insert str value into obj mapping with lower case key */
  ({ ...obj, [str.toLowerCase()] : str }), {})
);

console.log(uniques)

Here an object mapping case insenstive keys to case sensitive values is built via Array#reduce. This mapping ensures that unique values are obtained irrespective of case. The Object#values method is then used to transform that mapping to the required uniques array.

Update

If Object#values is not available in your browser, you can use the following solution:

let duplicates = ['Hello', 'Hi', 'hello'];

let mapping = duplicates.reduce((obj, str) => 
  ({ ...obj, [str.toLowerCase()] : str }), {})
let uniques = Object.keys(mapping).map(k => mapping[k])

console.log(uniques)

Hope that helps!

Dacre Denny
  • 26,362
  • 5
  • 28
  • 48
  • Thanks for reply, But i m getting some error "Property 'values' does not exist on type 'ObjectConstructor'." – Ankesh Pandey Dec 26 '19 at 09:41
  • @AnkeshPandey you're welcome, just updated answer. Does that help? – Dacre Denny Dec 26 '19 at 09:44
  • Again Thanks, Now its working.But is it an efficient way by looping all the elements of the list. Is there any other approach for the same? – Ankesh Pandey Dec 26 '19 at 09:55
  • Yep, just updated again to use mapping - in terms of efficiency, the for..in loop method will be the fastest alternate method. With the small amount of data your likely detailing with though, the updated "map" based method is probably fine as well, and quite a bit cleaner, code wise. Hope that's helpful :) – Dacre Denny Dec 26 '19 at 10:08
0

You can use _.uniqWith() with a callback as following:

let duplicates = ['Hello', 'Hi', 'hello'];

let uniques = _.uniqWith(duplicates, (a,b) => a.toLowerCase() === b.toLowerCase())

console.log(uniques);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
Harun Yilmaz
  • 6,857
  • 3
  • 21
  • 31
0

It's very simple with _.uniq and _.map

Here is an exmaple:

let uniqueData = _.uniq(_.map(duplicates, (d) => d.toLowerCase()));
Surjeet Bhadauriya
  • 4,714
  • 3
  • 26
  • 41
0

You can use _.uniqBy() with _.toLower() as iteratee:

const duplicates = ['Hello', 'Hi', 'hello'];

const result = _.uniqBy(duplicates, _.toLower);

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
Ori Drori
  • 145,770
  • 24
  • 170
  • 162
-1

You can use uniqBy methods

_.uniqBy(data, function (e) {
  return e.id;
});