Related
I am trying to search an array but in meantime I am able to search on just first name what I want to achieve I want to include last Name too . For example if user search which contain last name or first name I want to display a data . Could someone please help me how to resolve this issue.
Code
handleByNameChange = (e) => {
let value = e.target.value;
let updatedList = this.props.userData.allUsersForFilter;
updatedList = updatedList.filter(function (item) {
return item.firstName.toLowerCase().search(value.toLowerCase()) !== -1;
});
this.setState({
byNameInputValue: value,
items: updatedList,
});
};
Array of object
[
{firstName: 'Martin', lastName :'Jonas'},
{firstName:'Brad',lastName:'Mickle'},
{fitstName: 'Summer, lastName:'Bride'}
]
Create a function that takes an array to search, and array of property keys to search by, and a value to search for. If array of property keys is empty then no filter should probably occur, return all elements.
Use array:some to return true/false if using one of the property keys conditions is met.
Use string::includes to test if a string contains a substring.
searchBy function
const searchBy = (arr = [], searchKeys = [], value = '') => {
return arr.filter(item =>
searchKeys.length ? searchKeys.some(key =>
(item[key] || "").toLowerCase().includes(value.toLowerCase())
) : true
);
};
Usage
handleByNameChange = (e) => {
const { value } = e.target;
const updatedList = this.props.userData.allUsersForFilter;
this.setState({
byNameInputValue: value,
items: searchBy(updatedList, ['firstName', 'lastName'], value),
});
};
const data = [
{ firstName: "Martin", lastName: "Jonas" },
{ firstName: "Brad", lastName: "Mickle" },
{ firstName: "Summer", lastName: "Bride" },
{ firstName: "Axel", lastName: "Rod" },
{ firstName: "Mike", lastName: "Haxel" }
];
const searchBy = (arr = [], searchKeys = [], value = '') => {
return arr.filter(item =>
searchKeys.length ? searchKeys.some(key =>
(item[key] || "").toLowerCase().includes(value.toLowerCase())
) : true
);
};
console.log(searchBy(data, [], "Martin"));
console.log(searchBy(data, ["lastName"], ""));
console.log(searchBy(data, ["firstName"], "Martin"));
console.log(searchBy(data, ["firstName"], "Summer"));
console.log(searchBy(data, ["firstName", "lastName"], "ax"));
Addendum - Searching for combined full name
const searchByName = (arr = [], value = "") => {
return arr.filter(({ firstName = '', lastName = '' }) =>
[firstName, lastName, `${firstName} ${lastName}`].some(el =>
el.toLowerCase().includes(value.toLowerCase())
)
);
};
Tries to match first or last name, then full name
const data = [
{ firstName: "Martin", lastName: "Jonas" },
{ firstName: "Brad", lastName: "Mickle" },
{ firstName: "Summer", lastName: "Bride" },
{ firstName: "Axel", lastName: "Rod" },
{ firstName: "Mike", lastName: "Haxel" }
];
const searchByName = (arr = [], value = "") => {
return arr.filter(({ firstName = '', lastName = '' }) =>
[firstName, lastName, `${firstName} ${lastName}`].some(el =>
el.toLowerCase().includes(value.toLowerCase())
)
);
};
console.log(searchByName(data, "Martin"));
console.log(searchByName(data, ""));
console.log(searchByName(data, "Summer"));
console.log(searchByName(data, "ax"));
console.log(searchByName(data, "Mike Ha"));
All code in sandbox demo
Use some method on combining firstName and lastName array.
(Alternatively return (firstName check || lastName check)
data = [
{ firstName: "Martin", lastName: "Jonas" },
{ firstName: "Brad", lastName: "Mickle" },
{ firstName: "Summer", lastName: "Bride" },
];
value = "ride";
updatedList = data.filter(({ firstName, lastName }) =>
[firstName, lastName].some(
(name) => name.toLowerCase().search(value.toLowerCase()) !== -1
)
);
console.log(updatedList);
Is this you are looking for ?
const data = [
{firstName: 'Martin', lastName :'Jonas'},
{firstName:'Brad',lastName:'Mickle'},
{firstName:'Summer',lastName:'Bride'}
]
//anyName , which might be first Name or last Name
function filterData(anyName){
const res = data.filter(name => (name.firstName.includes(anyName)||name.lastName.includes(anyName)))
return res;
}
console.log(filterData('ride'))
You can do something like this:
const updatedList = [
{firstName: 'Martin', lastName :'Jonas'},
{firstName:'Brad',lastName:'Mickle'},
{firstName: 'Summer', lastName:'Bride'}
];
updatedList = updatedList.filter(function (item) {
return item.firstName.toLowerCase().search(value.toLowerCase()) !== -1 ||
item.lastName.toLowerCase().search(value.toLowerCase()) !== -1;
});
updatedList = updatedList.filter(function (item) {
if(value) {
return item.firstName.toLowerCase().indexOf(value.toLowerCase()) > -1 || item.lastName.toLowerCase().indexOf(value.toLowerCase()) > -1;
} else {
return "";
}
});
This is a very basic checking which is clear and concise one, it checks whether the first name or last name values have matched items with provided items or not.
I am able to get all unique properties from an array like this,
var array = [{
"firstName": "John",
"lastName": "Doe"
}, {
"firstName": "Anna",
"car": true
}, {
"firstName": "Peter",
"lastName": "Jones"
}];
var result = [];
array.reduce( function(pre, item) {
Object.keys(item).forEach(function(i){
if (result.indexOf(i) === -1){
result.push(i);
}
});
});
console.log(result);
However now I need this output,
[{
"firstName":"John, Anna, Peter",
"car": "true",
"lastName": "Doe, Jones"
}]
but I am not sure how to ?
Various ways. Here's one:
//get unique properties - hence Set, not array, so dups are omitted
let props = new Set(array.map(obj => Object.keys(obj)).flat());
//get non-falsy value for each prop type, as an array
let vals = [...props].map(prop => array.map(obj => obj[prop]).filter(a => a).join(', '));
//merge the two via Object.fromEntries()
let final = Object.fromEntries.call(null, [...props].map((prop, i) => [prop, vals[i]]));
You could achieve that by having a lookup object that store all values for a property. Then manipulate that object by joining all occurences
Below snippet could help you
var array = [
{
firstName: "John",
lastName: "Doe",
},
{
firstName: "Anna",
car: true,
},
{
firstName: "Peter",
lastName: "Jones",
},
]
var lookup = {}
var result = {}
array.forEach((obj) => {
Object.entries(obj).forEach(([key, val]) => {
if (!lookup[key]) {
lookup[key] = [val]
} else {
lookup[key].push(val)
}
})
})
Object.entries(lookup).forEach(([key, val]) => {
result[key] = val.join(', ')
})
console.log(result)
This question already has answers here:
"Variable" variables in JavaScript
(9 answers)
Closed 3 years ago.
just like the title said. i want to create a new object from data inside array below:
the name of the object is the first and last name.
//this is the input
arrayToObject([['Christ', 'Evans', 'Male'], ['Robert', 'Downey', 'Male']]);
//this is output that i want
// 1. Christ Evans:
// { firstName: 'Christ',
// lastName: 'Evans',
// gender: 'Male',
// 2. Robert Downey:
// { firstName: 'Robert',
// lastName: 'Downey',
// gender: 'Male',
// this is code that i write
function arrayToObject(arr) {
let ObjName=""
for (let i = 0; i<arr.length;i++){
let firstName=arr[i][0]
let lastName=arr[i][1]
let ObjName=firstName.concat(' ',lastName)
let gender=arr[1][2]
ObjName = { // idk how to make the object.
'firstName':firstName,
'lastName':lastName,
'gender':gender,
}
}
}
im struggling in the part where i can declare the object.
You could take a nested approach with Object.fromEntries and map the properties with a keys array.
var data = [['Christ', 'Evans', 'Male'], ['Robert', 'Downey', 'Male']],
keys = ['firstName', 'lastName', 'gender'],
result = Object.fromEntries(data.map(a => [
a.slice(0, 2).join(' '),
Object.fromEntries(keys.map((k, i) => [k, a[i]]))
]));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
I would suppose you want an array of objects with the following structure:
[
{
"firstName": "Christ",
"lastName": "Evans",
"gender": "Male"
},
{
"firstName": "Robert",
"lastName": "Downey",
"gender": "Male"
}
]
If that's the case, you can simply use Array.prototype.map, and in the callback you simply use array destructuring to unpack the second level array into firstName, lastName and gender:
function arrayToObject(arr) {
return arr.map((entry) => {
const [firstName, lastName, gender] = entry;
return {
firstName,
lastName,
gender
};
});
}
const a = arrayToObject([['Christ', 'Evans', 'Male'], ['Robert', 'Downey', 'Male']]);
console.log(a);
I have two JSON arrays like this. I want to merge their keyvalue pairs. They are some items which are common in both while they are some items which are uncommon.
var jsonData1 = [
{
firstName: "Sam",
age: "10"
},
{
firstName: "John",
age: "11"
},
{
firstName: "Jack",
age: "12"
},
{
firstName: "Pam",
age: "13"
},
{
firstName: "Tom",
age: "14"
},
{
firstName: "Mitch",
age: "15"
}
];
var jsonData2 = [
{
firstName: "Sam",
city: "London"
},
{
firstName: "John",
city: "New York"
},
{
firstName: "Jack",
city: "Paris"
},
{
firstName: "Pam",
city: "Moscow"
},
{
firstName: "Roger",
city: "Shanghai"
},
{
firstName: "Don",
city: "Jakarta"
}
];
As you can there are some firstName in 1st array which does not have city in 2nd array. Again there are some firstName in 2nd array which does not have city in 1st array.
I need to club these 2 array into one array, in case a firstName does not have age or city it will be assigned '' (blank string).
The new array will have 3 fields, there are some items which will be having values in 2 fields. They have a one field as blank string.
I want to do this using Vanilla JS, I do not want to use Jquery, Lodash and Underscore.
There are a number of ways to approach this, however one option would be to base this around the Array#reduce() method as follows:
const jsonData1=[{firstName:"Sam",age:"10"},{firstName:"John",age:"11"},{firstName:"Jack",age:"12"},{firstName:"Pam",age:"13"},{firstName:"Tom",age:"14"},{firstName:"Mitch",age:"15"}];
const jsonData2=[{firstName:"Sam",city:"London"},{firstName:"John",city:"New York"},{firstName:"Jack",city:"Paris"},{firstName:"Pam",city:"Moscow"},{firstName:"Roger",city:"Shanghai"},{firstName:"Don",city:"Jakarta"}];
/*
Use Array#concat() to combine both input arrays before performing
the merge. This will ensure that all items in both arrays are
processed and accounted for during the merge (which is important in
situations where the input arrays differ in length).
Object.values() is used to transform the dictionary resulting from
reduce() to an array
*/
var result = Object.values(
[].concat(jsonData1, jsonData2
).reduce((dict, item) => {
/*
We use Array#reduce is an intermediate step to construct a dictionary
which maps each unique "item.firstName" to a corresponding object
that contains the merged (or yet to be merged) data for this first
name
*/
var value = dict[item.firstName] || {}
/*
Use Object.assign() to merge existing data for "item.firstName" with
current item being processed. Also pass default values as first
argument to ensure all three key values are present in merge result
*/
value = Object.assign({ firstName : '', age : '', city : ''} , value, item)
/*
Update the dictionary with merged data
*/
dict[item.firstName] = value
return dict
}, {}))
console.log(result);
One possible approach:
const jsonData1=[{firstName:"Sam",age:"10"},{firstName:"John",age:"11"},{firstName:"Jack",age:"12"},{firstName:"Pam",age:"13"},{firstName:"Tom",age:"14"},{firstName:"Mitch",age:"15"}];
const jsonData2=[{firstName:"Sam",city:"London"},{firstName:"John",city:"New York"},{firstName:"Jack",city:"Paris"},{firstName:"Pam",city:"Moscow"},{firstName:"Roger",city:"Shanghai"},{firstName:"Don",city:"Jakarta"}];
const result = [].concat(jsonData1, jsonData2).reduce((acc, ele) => {
const existing = acc.find(x => x.firstName === ele.firstName);
if(!existing) return acc.concat({firstName: ele.firstName, city: ele.city || '', age: ele.age || ''});
Object.keys(ele).forEach(x => existing[x] = ele[x]);
return acc;
},[])
console.log(result);
I realize you've already accepted an answer but I figured I could provide an alternative, be it better or worse.
var jsonData1 = [{firstName: "Sam",age: "10"},{firstName: "John",age: "11"},{firstName: "Jack",age: "12"},{firstName: "Pam",age: "13"},{firstName: "Tom",age: "14"},{firstName: "Mitch",age: "15"}];
var jsonData2 = [{firstName: "Sam",city: "London"},{firstName: "John",city: "New York"},{firstName: "Jack",city: "Paris"},{firstName: "Pam",city: "Moscow"},{firstName: "Roger",city: "Shanghai"},{firstName: "Don",city: "Jakarta"}];
var defaults = {firstName: "", age: "", city: ""};
var data = [ ...jsonData1, ...jsonData2 ];
var names = [ ...new Set(data.map(i=>i.firstName)) ];
var res = names.map(n => data
.reduce((acc, jd) => jd.firstName === n ? {...acc, ...jd} : acc, defaults)
);
console.log(res);
var data combines the two arrays of data into one using spread syntax (array literals).
var names creates an array of unique names using Set.
map() iterates over the list of names, creating a single, merged object for each. That merge is done using reduce() and spread syntax (object literals).
I have my example array:
var person = [{
firstName:"John",
lastName:"Doe",
age:46
},
{
firstName:"Alexander",
lastName:"Bru",
age:46
},
{
firstName:"Alex",
lastName:"Bruce",
age:26
}];
Simple person.length gives me the length of my array, but I need to merge values when the age is the same. So if two people have same age return 1 no 2. Sorry for my bad English, I can made a mistakes.
Use Array#forEach method with an object reference for age.
var person = [{
firstName: "John",
lastName: "Doe",
age: 46
}, {
firstName: "Alexander",
lastName: "Bru",
age: 46
}, {
firstName: "Alex",
lastName: "Bruce",
age: 26
}];
// object for storing reference to age
var obj = {},
res = 0;
// iterate and count
person.forEach(function(v) {
// check age already not defined
if (!obj[v.age]) {
// define the property
obj[v.age] = true;
// increment count
res++;
}
});
console.log(res);
you can use underscore or similar library that supports groupBy:
_.size(_.groupBy(person, "age"))
Filter the array down to only those elements for which a find on the array for the first element with the same age yields the element itself, then take the length of the result:
array.filter(o1 => o1 === array.find(o2 => o2.age === o1.age)).length
Another idea involves using a little function called uniqueCount, which counts the number of unique values in a (sorted) array:
function uniqueCount(a) {
return a.reduce((cnt, elt, i) => a[i] === a[i-1] ? cnt : cnt + 1), 0);
}
Now you can create an array of all the ages, and do a count of its unique elements on it:
uniqueCount(array.map(e => e.age).sort(numeric))
If you are allowed to, you could add all the ages to a set and take its size.
const people = [{
firstName: "John",
lastName: "Doe",
age: 46
}, {
firstName: "Alexander",
lastName: "Bru",
age: 46
}, {
firstName: "Alex",
lastName: "Bruce",
age: 26
}];
const ages = new Set(people.map(person => person.age));
console.log(ages.size)