React table - format data to create subRows - javascript

I'm using react-table to create an expandible table.
In that example data are in this format:
[
{
"firstName": "wheel",
"lastName": "arch",
"age": 29,
"visits": 39,
"progress": 87,
"status": "single",
"subRows": [
{
"firstName": "singer",
"lastName": "paper",
"age": 24,
"visits": 35,
"progress": 55,
"status": "complicated",
"subRows": [
{
"firstName": "professor",
"lastName": "beam",
"age": 22,
"visits": 14,
"progress": 84,
"status": "single"
}, {...}
]
},
]
}
{
"firstName": "elevator",
"lastName": "contribution",
"age": 26,
"visits": 74,
"progress": 28,
"status": "relationship",
"subRows": [
{
"firstName": "debt",
"lastName": "honey",
"age": 3,
"visits": 31,
"progress": 31,
"status": "relationship"
}, {...}
]
},
{
"firstName": "cup",
"lastName": "media",
"age": 8,
"visits": 77,
"progress": 37,
"status": "single",
"subRows": undefined
}
]
So an array of objects and each object has a property subRows that can be undefinedd or an array of objects.
I've a flat dataset, so an array of objects and I want to recreate the above structure grouping by a property.
For example, this is my dataset:
const data = [
{animal: 'cat', name: 'mu', year: 2016},
{animal: 'cat', name: 'muji', year: 2021},
{animal: 'cat', name: 'mine', year: 2021},
{animal: 'dog', name: 'fido', year: 2000},
{animal: 'hamster', name: 'gerry', year: 2020},
{animal: 't-rex', name: 'dino', year: 2020},
{animal: 'sheep', name: 's', year: 2019},
{animal: 'sheep', name: 'sss', year: 2016},
]
and I would like that the animal column is expandible. How can I do?
I try groupBy by Lodash but obviously it's not the good method here.

const result = [
{animal: 'cat', name: 'mu', year: 2016},
{animal: 'cat', name: 'muji', year: 2021},
{animal: 'cat', name: 'mine', year: 2021},
{animal: 'dog', name: 'fido', year: 2000},
{animal: 'hamster', name: 'gerry', year: 2020},
{animal: 't-rex', name: 'dino', year: 2020},
{animal: 'sheep', name: 's', year: 2019},
{animal: 'sheep', name: 'sss', year: 2016},
].reduce(function (acc, obj) {
const x = acc.findIndex((entity)=>entity.animal===obj.animal);
if(x!== -1){
acc[x].subrows.push(obj)
}else{
const xx= {'animal':obj.animal,subrows:[obj]}
acc.push(xx)
}
return acc;
}, [])
console.log(result)

Related

How to populate dependable values into dropdown using javascript

I am trying to make a car year, make, model dependable values form. My arrays are in the following format. For the selected year and selected make, i want to populate the corresponding model value.
I have put unique year and make into separate another array. How will i achieve the intended result?
var car_arrays = [
{
id: 1,
year: 1909,
make: "Ford",
model: "Model T",
},
{
id: 2,
year: 1926,
make: "Chrysler",
model: "Imperial",
},
{
id: 3,
year: 1948,
make: "Citroën",
model: "2CV",
},
{
id: 4,
year: 1950,
make: "Hillman",
model: "Minx Magnificent",
},
{
id: 5,
year: 1953,
make: "Chevrolet",
model: "Corvette",
},
{
id: 7,
year: 1954,
make: "Cadillac",
model: "Fleetwood",
},
{
id: 6,
year: 1954,
make: "Chevrolet",
model: "Corvette",
},
{
id: 8,
year: 1955,
make: "Chevrolet",
model: "Corvette",
},
{
id: 9,
year: 1955,
make: "Ford",
model: "Thunderbird",
},
{
id: 10,
year: 1956,
make: "Chevrolet",
model: "Corvette",
},
{
id: 12,
year: 1957,
make: "BMW",
model: "600",
},
{
id: 11,
year: 1957,
make: "Chevrolet",
model: "Corvette",
},
{
id: 14,
year: 1958,
make: "BMW",
model: "600",
},
{
id: 13,
year: 1958,
make: "Chevrolet",
model: "Corvette",
},
{
id: 15,
year: 1958,
make: "Ford",
model: "Thunderbird",
},
{
id: 16,
year: 1959,
make: "Austin",
model: "Mini",
},
{
id: 18,
year: 1959,
make: "BMW",
model: "600",
},
{
id: 17,
year: 1959,
make: "Chevrolet",
model: "Corvette",
},
{
id: 19,
year: 1960,
make: "Chevrolet",
model: "Corvair",
},
{
id: 20,
year: 1960,
make: "Chevrolet",
model: "Corvette",
},
{
id: 22,
year: 1960,
make: "Fairthorpe",
model: "Rockette",
},
{
id: 21,
year: 1960,
make: "Fillmore",
model: "Fillmore",
},
{
id: 23,
year: 1961,
make: "Austin",
model: "Mini Cooper",
},
{
id: 26,
year: 1961,
make: "Chevrolet",
model: "Corvette",
},
{
id: 25,
year: 1961,
make: "Pontiac",
model: "Tempest",
},
{
id: 24,
year: 1961,
make: "Studebaker",
model: "Avanti",
},
{
id: 30,
year: 1962,
make: "Buick",
model: "Special",
},
{
id: 28,
year: 1962,
make: "Chevrolet",
model: "Corvette",
},
{
id: 27,
year: 1962,
make: "Pontiac",
model: "Grand Prix",
},
{
id: 29,
year: 1962,
make: "Studebaker",
model: "Avanti",
},
{
id: 31,
year: 1963,
make: "Austin",
model: "Mini",
},
{
id: 32,
year: 1963,
make: "Austin",
model: "Mini Cooper S",
},
{
id: 37,
year: 1963,
make: "Chevrolet",
model: "Corvair 500",
},
{
id: 38,
year: 1963,
make: "Chevrolet",
model: "Corvette",
},
{
id: 34,
year: 1963,
make: "Ford",
model: "E-Series",
},
{
id: 36,
year: 1963,
make: "Pontiac",
model: "Grand Prix",
},
{
id: 33,
year: 1963,
make: "Rambler",
model: "Classic",
},];
function getYear() {
var makeid = document.getElementById("makeid");
var select, option;
select = document.getElementById("yearid");
for (let y in year) {
option = document.createElement("option");
option.value = option.text = year[y];
select.add(option);
}
var selectyear = document.getElementById("yearid");
makeid.removeAttribute("disabled");
}
function getMake() {
var makeid, yearid, option;
makeidselect = document.getElementById("makeid");
yearidselect = document.getElementById("yearid");
for (let y in year) {
option = document.createElement("option");
option.value = option.text = year[y];
yearidselect.add(option);
console.log(yearidselect.value);
}
for (let x in make) {
option = document.createElement("option");
option.value = option.text = make[x];
makeidselect.add(option);
console.log(makeidselect.value);
}
var year = [
1909, 1926, 1948, 1950, 1953, 1954, 1955, 1956, 1957, 1958, 1959, 1960, 1961,
1962, 1963, 1964, 1965, 1966, 1967, 1968, 1969, 1970, 1971, 1972, 1973, 1974,
1975, 1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987,
1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013,
2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021,
];
var make = [
"Ford",
"Chrysler",
"Citroën",
"Hillman",
"Chevrolet",
"Cadillac",
"BMW",
"Austin",
"Fairthorpe",
"Fillmore",
"Pontiac",
"Studebaker",
"Buick",
"Rambler",
"Plymouth",
"Volkswagen",
"Jensen",
"Oldsmobile",
"Mercury",
"Dodge",
"Shelby",
"Porsche",
"Toyota",
"Mercedes-Benz",
"MG",
"Nissan",
"Honda",
"Mazda",
"Renault",
"Audi",
"Lincoln",
"Lotus",
"Maserati",
"Mitsubishi",
"Saab",
"Subaru",
"Suzuki",
"Lamborghini",
"Merkur",
"Land Rover",
"Acura",
"Lexus",
"Eagle",
"Alfa Romeo",
"Daihatsu",
"Geo",
"GMC",
"Hyundai",
"Infiniti",
"Isuzu",
"Jaguar",
"Jeep",
"Saturn",
"Volvo",
"HUMMER",
"Kia",
"Holden",
"Corbin",
"Daewoo",
"MINI",
"Maybach",
"Scion",
"Spyker",
"Aston Martin",
"Bentley",
"Panoz",
"Rolls-Royce",
"Spyker Cars",
"Ferrari",
"Hummer",
"Morgan",
"Peugeot",
"Foose",
"Aptera",
"Smart",
"Bugatti",
"Tesla",
"Ram",
"FIAT",
"Fiat",
"McLaren",
"BYD",
"McLaren Automotive",
"Mobility Ventures LLC",
"Pagani",
"Roush Performance",
"smart",
"SRT",
"Genesis",
"Karma",
"Koenigsegg",
"RUF Automobile",
"STI",
"Polestar",
"Kandi",
];
You can do something like this to populate the models dropdown
according to the values of year and make:
var CARS = [{
id: 1,
year: 1909,
make: 'Ford',
model: 'Model T',
},
{
id: 2,
year: 1926,
make: 'Chrysler',
model: 'Imperial',
},
{
id: 3,
year: 1948,
make: 'Citroën',
model: '2CV',
},
{
id: 4,
year: 1950,
make: 'Hillman',
model: 'Minx Magnificent',
},
{
id: 5,
year: 1953,
make: 'Chevrolet',
model: 'Corvette',
},
{
id: 7,
year: 1954,
make: 'Cadillac',
model: 'Fleetwood',
},
{
id: 6,
year: 1954,
make: 'Chevrolet',
model: 'Corvette',
},
{
id: 8,
year: 1955,
make: 'Chevrolet',
model: 'Corvette',
},
{
id: 9,
year: 1955,
make: 'Ford',
model: 'Thunderbird',
},
{
id: 10,
year: 1956,
make: 'Chevrolet',
model: 'Corvette',
},
{
id: 12,
year: 1957,
make: 'BMW',
model: '600',
},
{
id: 11,
year: 1957,
make: 'Chevrolet',
model: 'Corvette',
},
{
id: 14,
year: 1958,
make: 'BMW',
model: '600',
},
{
id: 13,
year: 1958,
make: 'Chevrolet',
model: 'Corvette',
},
{
id: 15,
year: 1958,
make: 'Ford',
model: 'Thunderbird',
},
{
id: 16,
year: 1959,
make: 'Austin',
model: 'Mini',
},
{
id: 18,
year: 1959,
make: 'BMW',
model: '600',
},
{
id: 17,
year: 1959,
make: 'Chevrolet',
model: 'Corvette',
},
{
id: 19,
year: 1960,
make: 'Chevrolet',
model: 'Corvair',
},
{
id: 20,
year: 1960,
make: 'Chevrolet',
model: 'Corvette',
},
{
id: 22,
year: 1960,
make: 'Fairthorpe',
model: 'Rockette',
},
{
id: 21,
year: 1960,
make: 'Fillmore',
model: 'Fillmore',
},
{
id: 23,
year: 1961,
make: 'Austin',
model: 'Mini Cooper',
},
{
id: 26,
year: 1961,
make: 'Chevrolet',
model: 'Corvette',
},
{
id: 25,
year: 1961,
make: 'Pontiac',
model: 'Tempest',
},
{
id: 24,
year: 1961,
make: 'Studebaker',
model: 'Avanti',
},
{
id: 30,
year: 1962,
make: 'Buick',
model: 'Special',
},
{
id: 28,
year: 1962,
make: 'Chevrolet',
model: 'Corvette',
},
{
id: 27,
year: 1962,
make: 'Pontiac',
model: 'Grand Prix',
},
{
id: 29,
year: 1962,
make: 'Studebaker',
model: 'Avanti',
},
{
id: 31,
year: 1963,
make: 'Austin',
model: 'Mini',
},
{
id: 32,
year: 1963,
make: 'Austin',
model: 'Mini Cooper S',
},
{
id: 37,
year: 1963,
make: 'Chevrolet',
model: 'Corvair 500',
},
{
id: 38,
year: 1963,
make: 'Chevrolet',
model: 'Corvette',
},
{
id: 34,
year: 1963,
make: 'Ford',
model: 'E-Series',
},
{
id: 36,
year: 1963,
make: 'Pontiac',
model: 'Grand Prix',
},
{
id: 33,
year: 1963,
make: 'Rambler',
model: 'Classic',
},
]
const YEARS = [
1909, 1926, 1948, 1950, 1953, 1954, 1955, 1956, 1957, 1958, 1959, 1960, 1961,
1962, 1963, 1964, 1965, 1966, 1967, 1968, 1969, 1970, 1971, 1972, 1973, 1974,
1975, 1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987,
1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013,
2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021,
]
const MAKES = [
'Ford',
'Chrysler',
'Citroën',
'Hillman',
'Chevrolet',
'Cadillac',
'BMW',
'Austin',
'Fairthorpe',
'Fillmore',
'Pontiac',
'Studebaker',
'Buick',
'Rambler',
'Plymouth',
'Volkswagen',
'Jensen',
'Oldsmobile',
'Mercury',
'Dodge',
'Shelby',
'Porsche',
'Toyota',
'Mercedes-Benz',
'MG',
'Nissan',
'Honda',
'Mazda',
'Renault',
'Audi',
'Lincoln',
'Lotus',
'Maserati',
'Mitsubishi',
'Saab',
'Subaru',
'Suzuki',
'Lamborghini',
'Merkur',
'Land Rover',
'Acura',
'Lexus',
'Eagle',
'Alfa Romeo',
'Daihatsu',
'Geo',
'GMC',
'Hyundai',
'Infiniti',
'Isuzu',
'Jaguar',
'Jeep',
'Saturn',
'Volvo',
'HUMMER',
'Kia',
'Holden',
'Corbin',
'Daewoo',
'MINI',
'Maybach',
'Scion',
'Spyker',
'Aston Martin',
'Bentley',
'Panoz',
'Rolls-Royce',
'Spyker Cars',
'Ferrari',
'Hummer',
'Morgan',
'Peugeot',
'Foose',
'Aptera',
'Smart',
'Bugatti',
'Tesla',
'Ram',
'FIAT',
'Fiat',
'McLaren',
'BYD',
'McLaren Automotive',
'Mobility Ventures LLC',
'Pagani',
'Roush Performance',
'smart',
'SRT',
'Genesis',
'Karma',
'Koenigsegg',
'RUF Automobile',
'STI',
'Polestar',
'Kandi',
]
MAKES.sort()
const yearSelection = document.getElementById('year')
const makeSelection = document.getElementById('make')
const modelSelection = document.getElementById('model')
const displayedCars = document.getElementById('cars')
for (let year of YEARS) {
const option = document.createElement('option')
option.textContent = year
option.value = year
yearSelection.appendChild(option)
}
for (let make of MAKES) {
const option = document.createElement('option')
option.textContent = make
option.value = make
makeSelection.appendChild(option)
}
const models = []
for (let car of CARS) {
const model = car.model
if (models.findIndex(m => m == model) == -1) {
const option = document.createElement('option')
option.className = 'car-model'
models.push(model)
option.textContent = model
option.value = model
modelSelection.appendChild(option)
}
}
const modelOptions = Object.values(document.querySelectorAll('.car-model'))
function populateModels() {
const selectedYear = yearSelection.value
const selectedMake = makeSelection.value
const filtered = CARS.filter(
car => car.year == selectedYear && car.make == selectedMake
)
for (let option of modelOptions) {
if (filtered.find(v => v.model == option.value)) {
option.hidden = false
} else {
option.hidden = true
}
}
if (filtered.length > 0) {
modelSelection.value = filtered[0].model
} else {
modelSelection.value = 'none'
}
}
populateModels()
yearSelection.onchange = () => populateModels()
makeSelection.onchange = () => populateModels()
<!DOCTYPE html>
<html>
<head>
<link rel="shortcut icon" href="#" type="image/x-icon" />
<meta charset="UTF-8" />
</head>
<body>
<select name="" id="year"></select>
<select name="" id="make"></select>
<select name="" id="model">
<option value="none" disabled hidden>No models found</option>
</select>
</body>
<script src="main.js"></script>
</html>
you can loop through the array:
let year = [], let make = [], ....
car_arrays.forEach(car => {
year.push(car.year)
make.push(car.make) ...
})

Filter and MAP Object inside Object in Javascript

How I can use the filter to populate the variable onlyAmountLess5? I want to filter only products where sales' amount < 5:
const products = [
{ id: 1, name: "bread", value: 2.0, category: "bakery", "sales":[{"day": "07/04/2021", "amount": 12}, {"day": "10/04/2021", "amount": 18}] },
{ id: 2, name: "apple", value: 6.5, category: "fruit", "sales":[{"day": "07/04/2021", "amount": 4}, {"day": "10/04/2021", "amount": 18}] },
{ id: 3, name: "pizza", value: 2.0, category: "food", "sales":[{"day": "07/04/2021", "amount": 5}, {"day": "10/04/2021", "amount": 18}]} ,
{ id: 4, name: "cheese", value: 7.0, category: "bakery", "sales":[{"day": "07/04/2021", "amount": 12}, {"day": "10/04/2021", "amount": 5}] },
{ id: 5, name: "milk", value: 2.2, category: "food", "sales":[{"day": "07/04/2021", "amount": 12}, {"dia": "10/04/2021", "amount": 3}]}
];
const onlyBakery = products.filter( p => p.category ==="bakery")
console.log(onlyBakery);
// List only product where sales amount < 5
const onlyAmountLess5 = products.filter(o => products.sales.amount < 4)
The field sales has two amounts. If you want to check them all you can do it like this:
const maxAmount = 5;
const onlyAmountLess5 = products.filter(product => product.sales.some(item => item.amount < maxAmount));
If you want to select the entry where all the amounts are less than 5, you can use every
Note that it would give an empty array, as for none of the example all objects have an amount lesser than 5.
Mind that < 4 is not the same as <5. You could also write <=4 instead.
const products = [
{ id: 1, name: "bread", value: 2.0, category: "bakery", "sales":[{"day": "07/04/2021", "amount": 12}, {"day": "10/04/2021", "amount": 18}] },
{ id: 2, name: "apple", value: 6.5, category: "fruit", "sales":[{"day": "07/04/2021", "amount": 4}, {"day": "10/04/2021", "amount": 18}] },
{ id: 3, name: "pizza", value: 2.0, category: "food", "sales":[{"day": "07/04/2021", "amount": 5}, {"day": "10/04/2021", "amount": 18}]} ,
{ id: 4, name: "cheese", value: 7.0, category: "bakery", "sales":[{"day": "07/04/2021", "amount": 12}, {"day": "10/04/2021", "amount": 5}] },
{ id: 5, name: "milk", value: 2.2, category: "food", "sales":[{"day": "07/04/2021", "amount": 12}, {"dia": "10/04/2021", "amount": 3}]}
];
const onlyAmountLess5 = products.filter(o =>o.sales.every(i => i.amount < 5));
console.log(onlyAmountLess5);
An example using < 13 to return 2 entries:
const products = [
{ id: 1, name: "bread", value: 2.0, category: "bakery", "sales":[{"day": "07/04/2021", "amount": 12}, {"day": "10/04/2021", "amount": 18}] },
{ id: 2, name: "apple", value: 6.5, category: "fruit", "sales":[{"day": "07/04/2021", "amount": 4}, {"day": "10/04/2021", "amount": 18}] },
{ id: 3, name: "pizza", value: 2.0, category: "food", "sales":[{"day": "07/04/2021", "amount": 5}, {"day": "10/04/2021", "amount": 18}]} ,
{ id: 4, name: "cheese", value: 7.0, category: "bakery", "sales":[{"day": "07/04/2021", "amount": 12}, {"day": "10/04/2021", "amount": 5}] },
{ id: 5, name: "milk", value: 2.2, category: "food", "sales":[{"day": "07/04/2021", "amount": 12}, {"dia": "10/04/2021", "amount": 3}]}
];
const onlyAmountLess5 = products.filter(o =>o.sales.every(i => i.amount < 13));
console.log(onlyAmountLess5);

Pivot/Transform json data columns to create new rows in javascript

I have a json file in the following format:
const data = [
{category: "A", country: "UK", name: "United Kingdom", country_id: "01", 2015: 5, 2016: 56, 2017: 10},
{category: "B", country: "UK", name: "United Kingdom", country_id: "01", 2015: 4, 2016: 10, 2017: 10},
{category: "C", country: "UK", name: "United Kingdom", country_id: "01", 2015: 10, 2016: 7, 2017: 45},
{category: "A", country: "PO", name: "Poland", country_id: "02", 2015: 9, 2016: 14, 2017: 10},
{category: "B", country: "PO", name: "Poland", country_id: "02", 2015: 10, 2016: 40, 2017: 0},
{category: "C", country: "PO", name: "Poland", country_id: "02", 2015: 60, 2016: 30, 2017: 74},
{category: "A", country: "CZ", name: "Czech Republic", country_id: "03", 2015: 30, 2016: 20, 2017: 10},
{category: "B", country: "CZ", name: "Czech Republic", country_id: "03", 2015: 15, 2016: 28, 2017: 1},
{category: "C", country: "CZ", name: "Czech Republic", country_id: "03", 2015: 16, 2016: 10, 2017: 2}
]
and I want to pivot the data to get the following format:
move 2015, 2016 and 2017 into a property named year
create a, b and c properties from category property values that will contain the different values.
have a line/object per country and year and any other ordinal categories I would like to keep.
const data = [
{country: "UK", name: "United Kingdom", country_id: "01", year: "2015", "a": 5 , "b": 4, "c": 10},
{country: "UK", name: "United Kingdom", country_id: "01", year: "2016", "a": 56 , "b": 10, "c": 7},
{country: "UK", name: "United Kingdom", country_id: "01", year: "2017", "a": 10 , "b": 10, "c": 45},
{country: "PO", name: "Poland", country_id: "02", year: "2015", "a": 9 , "b": 10, "c": 80},
{country: "PO", name: "Poland", country_id: "02", year: "2016", "a": 14 , "b": 40, "c": 30},
{country: "PO", name: "Poland", country_id: "02", year: "2017", "a": 10 , "b": 0, "c": 74},
{country: "CZ", name: "Czech Republic", country_id: "03", year: "2015", "a": 30 , "b": 15, "c": 16},
{country: "CZ", name: "Czech Republic", country_id: "03", year: "2016", "a": 20 , "b": 28, "c": 1},
{country: "CZ", name: "Czech Republic", country_id: "03", year: "2017", "a": 10 , "b": 1, "c": 2}
I tried writing a for loop inside a map method but I am unable to create a, b and c properties.
The rotation is done on the 3 lines commented 'Rotation'
To be able to do this we need to be able to access multiple rows of the original dataset. The strategy here builds us up to be able to do that.
Step 1. Get lists of the unique country_ids, years and categories
There are several ways to do this, and I have shown the easiest to understand method, which is to convert to a Set (which automatically removes duplicates) and then back to an Array for convenience of use.
Step 2. Move from a simple array, into an object
Instead of the rows being simply in sequence 0...8, we now have them in a 3x3 grid, addressible by country and category.
Step 3. Construct the desired output
Now within each country, we can extract all the data for a chosen year, by "plucking" the values for this year from the three different categories in the original data.
const data = [
{category: "A", country: "UK", name: "United Kingdom", country_id: "01", 2015: 5, 2016: 56, 2017: 10},
{category: "B", country: "UK", name: "United Kingdom", country_id: "01", 2015: 4, 2016: 10, 2017: 10},
{category: "C", country: "UK", name: "United Kingdom", country_id: "01", 2015: 10, 2016: 7, 2017: 45},
{category: "A", country: "PO", name: "Poland", country_id: "02", 2015: 9, 2016: 14, 2017: 10},
{category: "B", country: "PO", name: "Poland", country_id: "02", 2015: 10, 2016: 40, 2017: 0},
{category: "C", country: "PO", name: "Poland", country_id: "02", 2015: 60, 2016: 30, 2017: 74},
{category: "A", country: "CZ", name: "Czech Republic", country_id: "03", 2015: 30, 2016: 20, 2017: 10},
{category: "B", country: "CZ", name: "Czech Republic", country_id: "03", 2015: 15, 2016: 28, 2017: 1},
{category: "C", country: "CZ", name: "Czech Republic", country_id: "03", 2015: 16, 2016: 10, 2017: 2}
]
// Step 1. Extract the unique country_id, category Ids and years
const country_ids = Array(...new Set(data.map((x) => x.country_id)));
const categories = Array(...new Set(data.map((x) => x.category)));
const years = ["2015","2016","2017"];
// Step 2. Convert the source data into an object so that you can conveniently read off particular rows, in terms of COUNTRY_ID and CATEGORY
const sourceRows = {};
data.forEach((row) => {
if (!sourceRows[row.country_id]) {
sourceRows[row.country_id] = {};
}
sourceRows[row.country_id][row.category] = row;
});
// You can visualise the output here with this, if you want:
// console.log(sourceRows)
// Step 3. Create destination array, and poke a row into it for each country & year.
const destination = [];
country_ids.forEach((country_id) => {
years.forEach((year) => {
const sourceRow = sourceRows[country_id][categories[0]];
const destRow = {
country_id: country_id,
name: sourceRow.name,
country: sourceRow.country,
year: year,
a: sourceRows[country_id]["A"][year], // Rotation
b: sourceRows[country_id]["B"][year], // Rotation
c: sourceRows[country_id]["C"][year] // Rotation
};
destination.push(destRow);
});
});
console.log(destination);
Not the best solution, but this works. At the and, I made a workaround for the duplicates. You could use ...rest parameter to initialize years array if there will be new data for other years.
let newData = [];
let countries = data.map(({country})=> country)
let categories = data.map(({category})=> category)
let years = [2015,2016,2017];
countries.forEach(country => {
let countryData = data.filter(({country:c}) => c==country);
let yearData = {2015:{},2016:{},2017:{}};
years.forEach(year => {
categories.forEach(category => {
yearData[year][category] = countryData.find(({category:cat}) => cat==category)[year]
})
})
let {name,country_id}= data.find(({country:c}) => c == country);
Object.entries(yearData).forEach(([year,categories]) => {
newData.push({country,name,country_id,year, ...categories})
})
newData = newData.filter((data,i) => i%9<3)
console.log(newData)
})

Is it possible to sort an array of object by property of another object?

So i have an array of object that looks like this:
group: [
0: {id: "16", name: "P1", courseId: "6", mentorId: "1", chatUrl: false, students: {0: 1, 1: 10, 2: 11},…}
1: {id: "17", name: "C1", courseId: "7", mentorId: "3", chatUrl: false, students: {0: 15, 1: 16, 2: 18},…}
2: {id: "22", name: "P2", courseId: "6", mentorId: "1", chatUrl: false, students: {0: 12, 1: 13, 2: 9},…}
3: {id: "23", name: "C2", courseId: "7", mentorId: "3", chatUrl: false, students: {0: 17, 1: 19, 2: 20},…}
4: {id: "24", name: "DEV", courseId: "10", mentorId: "1", chatUrl: false,…}].
i'm trying to sort it by mentor name which is property of object in another array that looks like this:
mentor: [
0: {id: "0", firstName: "Daniel", about: false,…}
1: {id: "1", firstName: "Mark", aboutl:false,…}
2: {id: "3", firstName: "Eric", about: false,…}
3: {id: "6", firstName: "John", about: false,…} ]
The groups are related to mentors by property mentorId, so i have to compare property mentorId from group array with id from mentor array to get all mentors for groups and then sort the group by those mentors firstName. Is this even possible?
The output should display all the groups sorted alphabeticly by mentor firstname, something like this:
group: [
0: {id: "23", name: "C2", courseId: "7", mentorId: "3", chatUrl: false, students: {0: 17, 1: 19, 2: 20},…}
1: {id: "17", name: "C1", courseId: "7", mentorId: "3", chatUrl: false, students: {0: 15, 1: 16, 2: 18},…}
2: {id: "22", name: "P2", courseId: "6", mentorId: "1", chatUrl: false, students: {0: 12, 1: 13, 2: 9},…}
3: {id: "16", name: "P1", courseId: "6", mentorId: "1", chatUrl: false, students: {0: 1, 1: 10, 2: 11},…}
4: {id: "24", name: "DEV", courseId: "10", mentorId: "1", chatUrl: false,…}
]
You could first sort the mentors array by firstName property and then create an object where the key is the id and the value is index of that object in the sorted array. Then you can just use sort method on groups array and sort by the value of mentorId property in order object.
const groups = [{"id":"16","name":"P1","courseId":"6","mentorId":"1","chatUrl":false,"students":{"0":1,"1":10,"2":11}},{"id":"17","name":"C1","courseId":"7","mentorId":"3","chatUrl":false,"students":{"0":15,"1":16,"2":18}},{"id":"22","name":"P2","courseId":"6","mentorId":"1","chatUrl":false,"students":{"0":12,"1":13,"2":9}},{"id":"23","name":"C2","courseId":"7","mentorId":"3","chatUrl":false,"students":{"0":17,"1":19,"2":20}},{"id":"24","name":"DEV","courseId":"10","mentorId":"1","chatUrl":false}]
const mentors = [{"id":"0","firstName":"Daniel","about":false},{"id":"1","firstName":"Mark","aboutl":false},{"id":"3","firstName":"Eric","about":false},{"id":"6","firstName":"John","about":false}]
mentors.sort((a, b) => a.firstName.localeCompare(b.firstName))
const order = mentors.reduce((r, { id }, i) => (r[id] = i, r), {})
groups.sort((a, b) => order[a.mentorId] - order[b.mentorId])
console.log(groups)
var group= [
{id: "17", name: "C1", courseId: "7", mentorId: "3", chatUrl: false, students: {0: 15, 1: 16, 2: 18}},
{id: "16", name: "P1", courseId: "6", mentorId: "1", chatUrl: false, students: {0: 1, 1: 10, 2: 11}},
{id: "22", name: "P2", courseId: "6", mentorId: "1", chatUrl: false, students: {0: 12, 1: 13, 2: 9}},
{id: "23", name: "C2", courseId: "7", mentorId: "3", chatUrl: false, students: {0: 17, 1: 19, 2: 20}},
{id: "24", name: "DEV", courseId: "10", mentorId: "1", chatUrl: false}]
var mentor=[
{id: "0", firstName: "Daniel", about: false},
{id: "1", firstName: "Mark", aboutl:false},
{id: "3", firstName: "Eric", about: false},
{id: "6", firstName: "John", about: false}
]
group = group.sort( (a,b) => {
for(i=0;i<mentor.length;i++){
if (a.mentorId===mentor[i].id){a.mentorName=mentor[i].firstName}
if (b.mentorId===mentor[i].id){b.mentorName=mentor[i].firstName}
}
if(a.mentorName<b.mentorName){return -1}
else if(a.mentorName==b.mentorName){return 0}
else{return 1}
});
console.log(group);

Need to implement an algorithm to obtain the average value of the fields of the graph structure( graph tree)

I have such a task, please help with the solution!
There are graph nodes which have objects.
Please help me find the average value of the 'val' fields and the node with the minimum value of the 'val' field
Example graph structure(graph tree) Also i need implement this on JavaScript. Thank You very Match
var graph_structure = {
val: 74,
child: [{
val: 17,
child: [{
val: 34,
child: [{
val: 34,
child: [{
val: 65,
child: [{
val: 28,
child: [{val: 85},
{
val: 30,
child: [{val: 68},
{
val: 10,
child: [{
val: 100,
child: [{
val: 21,
child: [{val: 21},
{val: 64}]
},
{
val: 86
}
]
}
]
}
]
}
]
},
]
},
{
val: 22,
child: [{
val: 17,
child: [{val: 65}]
}]
}]
},
{
val: 53,
child: [{
val: 3,
child: [{
val: 98,
child: [{
val: 90,
child: [{
val: 76,
child: [{
val: 87,
child: [{
val: 52,
child: [{val: 56}]
}]
},
{val: 47},
{
val: 40,
child: [{
val: 80,
child: [{val: 34}]
},
{
val: 23,
child: [{val: 47},
{val: 92}]
},
{
val: 98,
child: [{val: 89},
{val: 16},
{val: 10}]
}]
}]
},
]
},
{
val: 35,
child: [{
val: 89,
child: [{
val: 76,
child: [{
val: 50,
child: [{val: 51},
{val: 90}]
},
{
val: 69,
child: [{val: 93},
{val: 98},
{val: 62}]
}]
}]
}]
}]
}]
},
]
}
]
}]
},
{
val: 98,
child: [{val: 85},
{
val: 85,
child: [{
val: 58,
child: [{
val: 81,
child: [{
val: 36,
child: [{
val: 45,
child: [{
val: 96,
child: [{
val: 15,
child: [{
val: 11,
child: [{val: 96}]
}]
},
{
val: 48,
child: [{
val: 4,
child: [{val: 74},
{val: 1}]
},
{val: 7}]
}]
},
{
val: 84,
child: [{val: 9},
{
val: 81,
child: [{
val: 10,
child: [{val: 67}]
}]
}]
}]
},
{
val: 85,
child: [{val: 53},
{
val: 7,
child: [{
val: 47,
child: [{
val: 74,
child: [{val: 30},
{val: 7},
{val: 12}]
},
{val: 22}]
},
{
val: 56,
child: [{
val: 51,
child: [{val: 45}]
},
{
val: 54,
child: [{val: 20},
{val: 62}]
}]
}]
}]
}]
}]
},
]
},
{
val: 62,
child: [{
val: 36,
child: [{
val: 39,
child: [{val: 20}]
},
{
val: 10,
child: [{
val: 91,
child: [{
val: 81,
child: [{
val: 59,
child: [{
val: 19,
child: [{val: 59},
{val: 16}]
},
{
val: 35,
child: [{val: 30}]
},
{
val: 6,
child: [{val: 27}]
}]
},
{
val: 89,
child: [{
val: 60,
child: [{val: 59}]
}]
}]
}]
},
]
}]
},
]
},
]
},
]
},
{
val: 8,
child: [{
val: 56,
child: [{
val: 55,
child: [{
val: 41,
child: [{
val: 17,
child: [{
val: 15,
child: [{
val: 40,
child: [{
val: 55,
child: [{val: 50},
{
val: 99,
child: [{val: 86},
{val: 90}]
}]
}]
},
{
val: 85,
child: [{
val: 36,
child: [{
val: 39,
child: [{val: 45}]
}]
}]
},
{
val: 78,
child: [{
val: 24,
child: [{
val: 93,
child: [{val: 8}]
},
{
val: 26,
child: [{val: 5}]
}]
},
{val: 36}]
}]
},
{val: 13}]
},
]
},
{
val: 10,
child: [{
val: 0,
child: [{
val: 77,
child: [{
val: 46,
child: [{
val: 72,
child: [{
val: 17,
child: [{val: 10},
{val: 67}]
},
{val: 48},
{val: 60}]
},
{
val: 98,
child: [{
val: 12,
child: [{val: 61},
{val: 27}]
}]
}]
}]
},
]
}
]
}
]
}
]
}
]
}
]};
You could create recursive function with for...in loop and first calculate total sum and total number of nodes and then use those 2 values to calculate average.
var graph_structure = {"val":74,"child":[{"val":17,"child":[{"val":34,"child":[{"val":34,"child":[{"val":65,"child":[{"val":28,"child":[{"val":85},{"val":30,"child":[{"val":68},{"val":10,"child":[{"val":100,"child":[{"val":21,"child":[{"val":21},{"val":64}]},{"val":86}]}]}]}]}]},{"val":22,"child":[{"val":17,"child":[{"val":65}]}]}]},{"val":53,"child":[{"val":3,"child":[{"val":98,"child":[{"val":90,"child":[{"val":76,"child":[{"val":87,"child":[{"val":52,"child":[{"val":56}]}]},{"val":47},{"val":40,"child":[{"val":80,"child":[{"val":34}]},{"val":23,"child":[{"val":47},{"val":92}]},{"val":98,"child":[{"val":89},{"val":16},{"val":10}]}]}]}]},{"val":35,"child":[{"val":89,"child":[{"val":76,"child":[{"val":50,"child":[{"val":51},{"val":90}]},{"val":69,"child":[{"val":93},{"val":98},{"val":62}]}]}]}]}]}]}]}]}]},{"val":98,"child":[{"val":85},{"val":85,"child":[{"val":58,"child":[{"val":81,"child":[{"val":36,"child":[{"val":45,"child":[{"val":96,"child":[{"val":15,"child":[{"val":11,"child":[{"val":96}]}]},{"val":48,"child":[{"val":4,"child":[{"val":74},{"val":1}]},{"val":7}]}]},{"val":84,"child":[{"val":9},{"val":81,"child":[{"val":10,"child":[{"val":67}]}]}]}]},{"val":85,"child":[{"val":53},{"val":7,"child":[{"val":47,"child":[{"val":74,"child":[{"val":30},{"val":7},{"val":12}]},{"val":22}]},{"val":56,"child":[{"val":51,"child":[{"val":45}]},{"val":54,"child":[{"val":20},{"val":62}]}]}]}]}]}]}]},{"val":62,"child":[{"val":36,"child":[{"val":39,"child":[{"val":20}]},{"val":10,"child":[{"val":91,"child":[{"val":81,"child":[{"val":59,"child":[{"val":19,"child":[{"val":59},{"val":16}]},{"val":35,"child":[{"val":30}]},{"val":6,"child":[{"val":27}]}]},{"val":89,"child":[{"val":60,"child":[{"val":59}]}]}]}]}]}]}]}]}]},{"val":8,"child":[{"val":56,"child":[{"val":55,"child":[{"val":41,"child":[{"val":17,"child":[{"val":15,"child":[{"val":40,"child":[{"val":55,"child":[{"val":50},{"val":99,"child":[{"val":86},{"val":90}]}]}]},{"val":85,"child":[{"val":36,"child":[{"val":39,"child":[{"val":45}]}]}]},{"val":78,"child":[{"val":24,"child":[{"val":93,"child":[{"val":8}]},{"val":26,"child":[{"val":5}]}]},{"val":36}]}]},{"val":13}]}]},{"val":10,"child":[{"val":0,"child":[{"val":77,"child":[{"val":46,"child":[{"val":72,"child":[{"val":17,"child":[{"val":10},{"val":67}]},{"val":48},{"val":60}]},{"val":98,"child":[{"val":12,"child":[{"val":61},{"val":27}]}]}]}]}]}]}]}]}]}]}
function calc(data) {
return (function repeat(data, res) {
for(let i in data) {
if(data.val) {
res.nodes++;
res.total += data.val
if(!res.min) res.min = data
else if(res.min.val > data.val) res.min = data
}
if(typeof data[i] == 'object') repeat(data[i], res)
}
return res
})(data, {min: null, nodes: 0, total: 0})
}
let res = calc(graph_structure);
res.avg = res.total / res.nodes;
console.log(res)

Categories

Resources