比较映射数组内部的对象

时间:2019-04-15 14:42:10

标签: javascript arrays

我有一个对象数组:该数组内部有另一个数组,其中包含带有用户键,值对的对象列表。我需要将此数组映射到列表中,并且,如果用户具有相同的名称和姓氏,请确保将其映射到其下的两个位置。我怎样才能做到这一点?我的第一种方法是比较索引,但是没有用。我还找到了一个辅助函数来比较数组中的值,但似乎无法将其集成到映射函数中。有什么想法吗?

数组:

[
    {
        "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>))}

2 个答案:

答案 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"]
相关问题