Lodash sortByOrder with provided alphabet - javascript

I need to sort an array of objects by provided keys. Sorting must be case-insensitive and use provided alphabet. For example let's take initial data that looks like this:
var notOrdered = [{
date: "11-12-2015",
name: "Tomasz",
age: 50,
products: "FDGS",
rate: 500
}, {
date: "12-11-2015",
name: "Łukasz",
age: 54,
products: "ŁBDGS",
rate: 110
}, {
date: "11-12-2015",
name: "Jan",
age: 24,
products: "ŻDGS",
rate: 1000
}, {
date: "11-12-2015",
name: "Łucja",
age: 18,
products: "AEBDGS",
rate: 50
}];
var keys = ["date", "rate", "name"];
var directions = [true, false, true];
var alphabet = '01234567989aąbcćdeęfghijklłmnńoóprsśtuvwxyzźż'
So the result I'm looking for is:
var ordered = [{
date: "11-12-2015",
name: "Łucja",
age: 18,
products: "AEBDGS",
rate: 50
}, {
date: "11-12-2015",
name: "Jan",
age: 24,
products: "ŻDGS",
rate: 50
}, {
date: "11-12-2015",
name: "Tomasz",
age: 50,
products: "FDGS",
rate: 500
}, {
date: "12-11-2015",
name: "Łukasz",
age: 54,
products: "ŁBDGS",
rate: 110
}];
Using lodash's sortByOrder function var ordered = _.sortByOrder(notOrdered, keys, directions) takes care of sorting using provided keys and directions - one after another. And it works great. What I need now is to use provided alphabet order instead of the default one and make comparisons case-insensitive.
All the chars that are not listed in the provided alphabet should be compared the default way. I cannot use localCompare, because I need to support old IE and mobile browsers.
The question is: can I somehow make lodash's sortByOrder function to use custom alphabet and if so, how to do it?

Related

Parse JSON-like string into object using JavaScript

I have a problem about using JSON-like string parser: sometimes users will not input a correct strict JSON string. For example:
input =
"name: John,
age: 20,
products: [
{ id : 100, name: flower },
{ id : 101, name: snack },
],
home: New York,
education: {
highSchool: {
name: Stuyvesant High School,
GPA: 3.2
},
college: {
name: Fordham University,
GPA: 2.8
}
}"
The input above is not able to parse using JSON.parse() because both key and value does not fit contained by "" (name: John instead of "name": "John")
How can we get the expected output like this:
console.log(customParser(input));
//expected
/*
name: "John",
age: 20,
products: (2) [{...}, {...}]
home: "New York"
education: (2) {highSchool: {...}, college: {...}}
*/
As an alternative to writing your own parser from scratch, you might consider interpreting the user input as YAML. For example, the Node.js command require("js-yaml").load(input) converts your example input into the following Javascript object:
{
name: 'John,',
age: '20,',
products: [ { id: 100, name: 'flower' }, { id: 101, name: 'snack' } ],
home: 'New York,',
education: {
highSchool: { name: 'Stuyvesant High School', GPA: 3.2 },
college: { name: 'Fordham University', GPA: 2.8 }
}
}
Except for the trailing commas at the end of the string-valued properties, that is what you want. Either educate your users to leave these commas out, or write a pre-processor that removes them before calling the .load function of js-yaml.

Counting the occurrences of an object in an array of objects based on a key [duplicate]

This question already has answers here:
Group array of objects by value and get count of the groups
(2 answers)
Closed last year.
I have an array of objects as follows :
let people = [
{ name: "Emily", age: 15 }, { name: "Emma", age: 16 },
{ name: "Stacy", age: 18 }, { name: "Emily", age: 15 },
{ name: "Jennifer", age: 12 }
];
I need to return the result containing the age as the key and frequency as it's corresponding value as follows :
{ 15 : 2, 16 : 1, 18 : 1, 12 : 1 }
I wish I could implement this using both forEach() and reduce().
Using Array#reduce:
const people = [ { name: "Emily", age: 15 }, { name: "Emma", age: 16 }, { name: "Stacy", age: 18 }, { name: "Emily", age: 15 }, { name: "Jennifer", age: 12 } ];
const ageCount = people.reduce((map, { age }) => ({
...map,
[age]: (map[age] || 0) + 1
}), {});
console.log(ageCount);

Javascript filter array based on another array of object

I am trying to merge the two arrays based on Arr1 values. If the array 2 doesn't has the respective value in array1, it should return as empty object with values. Below are the two arrays:
Arr1 = [{
name: "raj",
age: 20
}, {
name: "ravi",
age: 40
}];
Arr2 = ['raj', 'ravi', 'arnold'];
Javascript Code is,
let result = Arr1.filter(o1 => Arr2.some(o2 => o2 === o1.name));
I am getting the result as below,
result = [{
name: "raj",
age: 20
}, {
name: "ravi",
age: 40
}];
But expected array should be,
[{
name: "raj",
age: 20
}, {
name: "ravi",
age: 40
}, {
name: "arnold",
age: null,
available: no
}];
Any suggestions?
You can use Array#map along with Array#find to obtain your expected result.
let Arr1 = [{
name: "raj",
age: 20
}, {
name: "ravi",
age: 40
}];
let Arr2 = ['raj', 'ravi', 'arnold'];
let result = Arr2.map(x=>
Arr1.find(({name})=>name===x)??{name:x,age:null,available: 'no'}
);
console.log(result);
I suggest a different approach and take an object for the given data and map the wanted names for eithe the given data or a new object.
This approach has a better big O, becaus it take a hash table and works fast for great data.
const
array1 = [{ name: "raj", age: 20 }, { name: "ravi", age: 40 }],
array2 = ['raj', 'ravi', 'arnold'],
data = array1.reduce((r, o) => (r[o.name] = o, r), {}),
result = array2.map(name => data[name] || { name, age: null, available: 'no' });
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comparing collection keys in RxJS?

Wanted to see if RxJS has a quick / elegant way of doing this.
Suppose we have two different array of objects. For example:
A1:
[{ name: 'Sue', age: 25 },
{ name: 'Joe', age: 30 },
{ name: 'Frank', age: 25 },
{ name: 'Sarah', age: 35 }]
A2:
[{ name: 'Sue', age: 25 },
{ name: 'Frank', age: 25 },
{ name: 'Joe', age: 30 },
{ name: 'Sarah', age: 35 }]
The keys we want to compare are identified by the name property.
I was thinking about just producing two arrays of all the names filtering out the duplicates, and then comparing them to make sure they are equal, but thought perhaps RxJS has a slick way of doing this and could also emit an observable of any names that don't have a match?
You can try merging the two lists and then applying the distinct operator with a key selector function (to specify key is "name") so that you get a stream of the de-duped items.
https://rxjs-dev.firebaseapp.com/api/operators/distinct

Uncaught TypeError: arrayName.sort is not a function

I am trying to sort the values using the map method.
but I am getting an error Uncaught TypeError: arrayName.sort is not a function.
can you tell me how to sort it.
can you tell me how to solve using the below methods, since I am learning functional programmming
.map()
.filter()
.find()
.replace()
.reduce()
forEach()
providing my code below.
// ARRAY 2
const newieyork = [
{
name: 'Michelle',
age: 19,
coder:true,
gender: 'f',
us: true,
},
{
name: 'Sam',
age: 25,
coder:false,
gender: 'm',
us: false,
},
{
name: 'Ivy',
age: 26,
coder:true,
gender: 'f',
us: false,
},
{
name: 'Nick',
age: 32,
coder:true,
gender: 'm',
us: true,
},
{
name: 'Jim Beglin',
age: 65,
coder:false,
gender: 'm',
us: true,
},
]
// Part 1 - List all users in US in ascending order
newieyork.sort();
//console.log("newieyork.sort();--->", newieyork.sort());
newieyork.map(function(newieyork){
//console.log("texasss.name--->", newieyork.name);
let arrayName =[];
arrayName = newieyork.name;
console.log("arrayName--->", arrayName.sort());
});
In your code you are assigning to a string:
let arrayName =[];
arrayName = newieyork.name; // Assigning to a string
sort is not a method on a string.

Categories

Resources