我有一个对象数组:该数组内部有另一个数组,其中包含带有用户键,值对的对象列表。我需要将此数组映射到列表中,并且,如果用户具有相同的名称和姓氏,请确保将其映射到其下的两个位置。我怎样才能做到这一点?我的第一种方法是比较索引,但是没有用。我还找到了一个辅助函数来比较数组中的值,但似乎无法将其集成到映射函数中。有什么想法吗?
数组:
[
{
"users": [
{
"name": "John",
"last-name": "Edmus",
"location": "USA"
},
{
"name": "John",
"last-name": "Edmus",
"location": "California"
},
{
"name": "Jane",
"last-name": "Edmus"
"location": "USA"
}
]
},
]
理想的输出:
<ul>
<li>"John Edmus, location: USA and California"</li>
<li> "Jane Edmus, location: USA"</li>
<ul>
到目前为止我尝试过的事情
mapArray= () =>{
return test.map(i =>
i.users.map(user =>
<ul>{users.map.user.name.index + users.map.user.last-name.index === users.map.user.name.index + users.map.user.last-name.index + 2 : <li> {user.name} {user.last-name}</li>))}
答案 0 :(得分:1)
您的问题始于数据:阵列中的某些对象应该合并,但不是。让我们先解决这个问题。
让我们首先定义我们认为重复的东西。为此,我们将定义一个hash
函数,该函数为每个用户输出一个唯一的字符串。一分钟后,您就会明白为什么。
User.hash = user => `${user.firstName} ${user.lastName}`;
// Here, we define our client-side user
const User = (firstName, lastName, locations) => ({
firstName,
lastName,
locations
});
// This defines what makes a user unique
User.hash = user => `${user.firstName} ${user.lastName}`;
// A helper to easily map the users from our source data
// to client-side users
User.fromServerData = (userData) => User(
userData.name, userData["last-name"], [userData.location]
);
// Use our User logic on your data
const data = [{users:[{name:"John","last-name":"Edmus",location:"USA"},{name:"John","last-name":"Edmus",location:"California"},{name:"Jane","last-name":"Edmus",location:"USA"}]}];
const users = data[0].users.map(User.fromServerData);
// Log a list of user hashes
console.log(users.map(User.hash));
从控制台日志中可以看到,我们有一个重复的用户!
查找重复项现在是按哈希分组的问题。为此,我将定义一个快速的groupBy
帮助器。如果您想知道此帮助程序的工作原理,可以在Google js groupBy
上进行搜索或查看下划线或ramda之类的库实现。
const User = (firstName, lastName, locations) => ({
firstName,
lastName,
locations
});
User.hash = user => `${user.firstName} ${user.lastName}`;
User.fromServerData = (userData) => User(
userData.name, userData["last-name"], [userData.location]
);
const data = [{users:[{name:"John","last-name":"Edmus",location:"USA"},{name:"John","last-name":"Edmus",location:"California"},{name:"Jane","last-name":"Edmus",location:"USA"}]}];
const users = data[0].users.map(User.fromServerData);
console.log(groupBy(User.hash, users));
// Utils
function groupBy(getKey, xs) { return xs
.map(x => [getKey(x), x])
.reduce((acc, [k, v]) => Object.assign(acc, {
[k]: (acc[k] || []).concat(v)
}), {});
}
现在,我们将两个John整齐地排列在一个数组中。
剩下的就是合并重复项。像hash
方法一样,我们将逻辑分开:
User.merge = (userA, userB) => User(
userB.firstName,
userB.lastName,
[ ...userA.locations, ...userB.locations ]
);
使用此功能,我们可以将任何重复用户列表与reduce
合并:
const mergedUsers = duplicateUsers.reduce(User.merge);
请注意,您可以在没有种子的情况下使用reduce
,但是如果您将其传递给空数组,它将中断。在下面的代码段中,我们确定将永远不会有一个空数组。无论如何,我都会将一个空用户作为种子包含进来,以防万一您在其他地方重复使用它。
const User = (firstName, lastName, locations) => ({
firstName,
lastName,
locations
});
User.hash = user => `${user.firstName} ${user.lastName}`;
User.merge = (userA, userB) => User(
userB.firstName,
userB.lastName,
[...userA.locations, ...userB.locations]
);
User.empty = () => User(null, null, []);
User.fromServerData = (userData) => User(
userData.name, userData["last-name"], [userData.location]
);
// Use our User logic on your data
const data = [{users:[{name:"John","last-name":"Edmus",location:"USA"},{name:"John","last-name":"Edmus",location:"California"},{name:"Jane","last-name":"Edmus",location:"USA"}]}];
const users = data[0].users.map(User.fromServerData);
console.log(
Object
.values(groupBy(User.hash, users))
.map(duplicates => duplicates
.reduce(User.merge, User.empty())
)
);
// Utils
function groupBy(getKey, xs) {
return xs
.map(x => [getKey(x), x])
.reduce((acc, [k, v]) => Object.assign(acc, {
[k]: (acc[k] || []).concat(v)
}), {});
};
现在数据已经整理好了,我们可以在没有任何自定义逻辑的情况下呈现到列表:
User.render = ({ firstName, lastName, locations }) =>
`<li>
${firstName} ${lastName} (${locations.join(" and ")})
</li>`;
const view = `
<ul>
${users.map(User.render).join("")}
</ul>`;
const User = (firstName, lastName, locations) => ({
firstName,
lastName,
locations
});
User.hash = user => `${user.firstName} ${user.lastName}`;
User.merge = (userA, userB) => User(
userB.firstName,
userB.lastName,
[...userA.locations, ...userB.locations]
);
User.empty = () => User(null, null, []);
User.render = user => `<li>
${user.firstName} ${user.lastName}
(${user.locations.join(" and ")}) </li>`;
User.fromServerData = (userData) => User(
userData.name, userData["last-name"], [userData.location]
);
const data = [{users:[{name:"John","last-name":"Edmus",location:"USA"},{name:"John","last-name":"Edmus",location:"California"},{name:"Jane","last-name":"Edmus",location:"USA"}]}];
const userGroups = groupBy(
User.hash,
data[0].users.map(User.fromServerData)
);
const users = Object.values(userGroups)
.map(duplicates => duplicates
.reduce(User.merge, User.empty())
);
const view = `<ul>${users.map(User.render).join("")}</ul>`;
document.querySelector(".app").innerHTML = view;
// Utils
function groupBy(getKey, xs) {
return xs
.map(x => [getKey(x), x])
.reduce((acc, [k, v]) => Object.assign(acc, {
[k]: (acc[k] || []).concat(v)
}), {});
};
<div class="app"></div>
答案 1 :(得分:0)
评论太大了
也许这段代码可以帮助您:
var json = '[{"users": [{"name": "John","last_name": "Edmus","location": "USA"},{"name": "John","last_name": "Edmus","location": "California"},{"name": "Jane","last_name": "Edmus","location": "USA"}]}]';
var to_array = JSON.parse(json);
var array_tmp = Array();
for(var item in to_array[0].users) {
var element = to_array[0].users[item];
var key = element.name +" "+ element.last_name;
if( typeof array_tmp[key] !== "undefined" ) {
array_tmp[key] += " and "+ element.location;
}
else {
array_tmp[key] = element.location;
}
}
console.log(array_tmp);
输出将是:
[John Edmus: "USA and California", Jane Edmus: "USA"]