如何比较两个对象数组并在第二个对象中存在值的情况下更新第一个对象。

huangapple go评论56阅读模式
英文:

How to compare two array of objects and update the first object if value is present in the second object

问题

以下是翻译好的部分:

我有两个对象数组,并且如果第二个数组中存在相似的数据,我想更新第一个数组中的数据。我尝试使用 forEach,但在遍历响应数组的第二个元素后出现错误。

第一个对象数组:

const body = [{
    slot: "9:00",
    status: "Available",
    clientName: "",
    doctorName: ""
  }, {
    slot: "9:30",
    status: "Available",
    clientName: "",
    doctorName: ""
  }, {
    slot: "1:00",
    status: "Available",
    clientName: "",
    doctorName: ""
  }, {
    slot: "1:30",
    status: "Available",
    clientName: "",
    doctorName: ""
  }
]

第二个对象数组:

const response = [{
  clientName: "John Doe",
  doctorName: "Paul Pierce",
  slot: "09:00",
  status: "Not Available"
}, {
  clientName: "James Bond",
  doctorName: "Chris Paul",
  slot: "01:00",
  status: "Not Available"
}]

这是我的期望输出:

const result = [{
    slot: "9:00",
    status: "Not Available",
    clientName: "John Doe",
    doctorName: "Paul Pierce"
  }, {
    slot: "9:30",
    status: "Available",
    clientName: "",
    doctorName: ""
  }, {
    slot: "1:00",
    status: "Not Available",
    clientName: "James Bond",
    doctorName: "Chris Paul"
  }, {
    slot: "1:30",
    status: "Available",
    clientName: "",
    doctorName: ""
  }
]
英文:

I have two arrays of objects, and I want to update the data in the first array if there is a similar data in the second array. I tried using forEach, but I get an error after looping through the second element of the response array.

First array of objects:

const body = [{
    slot: "9:00",
    status: "Available",
    clientName: "",
    doctorName: ""
  }, {
    slot: "9:30",
    status: "Available",
    clientName: "",
    doctorName: ""
  }, {
    slot: "1:00",
    status: "Available",
    clientName: "",
    doctorName: ""
  }, {
    slot: "1:30",
    status: "Available",
    clientName: "",
    doctorName: ""
  }
]

Second array of objects:

const response = [{
  clientName: "John Doe",
  doctorName: "Paul Pierce",
  slot: "09:00",
  status: "Not Available"
}, {
  clientName: "James Bond",
  doctorName: "Chris Paul",
  slot: "01:00",
  status: "Not Available"
}]

This is my desired output:

const result = [{
    slot: "9:00",
    status: "Not Available",
    clientName: "John Doe",
    doctorName: "Paul Pierce"
  }, {
    slot: "9:30",
    status: "Available",
    clientName: "",
    doctorName: ""
  }, {
    slot: "1:00",
    status: "Not Available",
    clientName: "James Bond",
    doctorName: "Chris Paul"
  }, {
    slot: "1:30",
    status: "Available",
    clientName: "",
    doctorName: ""
  }
]

答案1

得分: 1

对于body中的每个元素,在response中找到对应的信息。如果找不到,返回未修改的原始信息;否则,合并它们并返回一个新的对象。

正如@trincot所指出的,数据具有两种不同的时间格式。我使用String#padStart来处理这个问题;然而,最好在数据源处进行修改。

body.map(originalSlot => {
	const slotInfo = response.find(
      ({ slot }) => slot === originalSlot.slot.padStart(5, 0)
    );

	if (!slotInfo) {
		return originalSlot;
	}

	return { ...originalSlot, ...slotInfo, slot: originalSlot.slot };
});

试一下:

<!-- begin snippet: js hide: true console: true babel: false -->

<!-- language: lang-js -->
const body = [
  {
    slot: '9:00',
    status: 'Available',
    clientName: '',
    doctorName: ''
  },
  {
    slot: '9:30',
    status: 'Available',
    clientName: '',
    doctorName: ''
  },
  {
    slot: '1:00',
    status: 'Available',
    clientName: '',
    doctorName: ''
  },
  {
    slot: '1:30',
    status: 'Available',
    clientName: '',
    doctorName: ''
  }
];

const response = [
  {
    clientName: 'John Doe',
    doctorName: 'Paul Pierce',
    slot: '09:00',
    status: 'Not Available'
  },
  {
    clientName: 'James Bond',
    doctorName: 'Chris Paul',
    slot: '01:00',
    status: 'Not Available'
  }
];

const results = body.map(originalSlot => {
	const slotInfo = response.find(
    ({ slot }) => slot === originalSlot.slot.padStart(5, 0)
  });

	if (!slotInfo) {
		return originalSlot;
	}

	return { ...originalSlot, ...slotInfo, slot: originalSlot.slot };
});

console.log(results);

<!-- end snippet -->
英文:

For each element in body, find the corresponding info in response. If not found, return original one without modifying; else, merge them and return a new object.

As @trincot has pointed out, the data has two different time formats. I deal with this using String#padStart; however, it is best that they be modified at the source.

body.map(originalSlot =&gt; {
	const slotInfo = response.find(
      ({ slot }) =&gt; slot === originalSlot.slot.padStart(5, 0)
    );

	if (!slotInfo) {
		return originalSlot;
	}

	return { ...originalSlot, ...slotInfo, slot: originalSlot.slot };
});

Try it:

<!-- begin snippet: js hide: true console: true babel: false -->

<!-- language: lang-js -->

const body = [
  {
    slot: &#39;9:00&#39;,
    status: &#39;Available&#39;,
    clientName: &#39;&#39;,
    doctorName: &#39;&#39;
  },
  {
    slot: &#39;9:30&#39;,
    status: &#39;Available&#39;,
    clientName: &#39;&#39;,
    doctorName: &#39;&#39;
  },
  {
    slot: &#39;1:00&#39;,
    status: &#39;Available&#39;,
    clientName: &#39;&#39;,
    doctorName: &#39;&#39;
  },
  {
    slot: &#39;1:30&#39;,
    status: &#39;Available&#39;,
    clientName: &#39;&#39;,
    doctorName: &#39;&#39;
  }
];

const response = [
  {
    clientName: &#39;John Doe&#39;,
    doctorName: &#39;Paul Pierce&#39;,
    slot: &#39;09:00&#39;,
    status: &#39;Not Available&#39;
  },
  {
    clientName: &#39;James Bond&#39;,
    doctorName: &#39;Chris Paul&#39;,
    slot: &#39;01:00&#39;,
    status: &#39;Not Available&#39;
  }
];

const results = body.map(originalSlot =&gt; {
	const slotInfo = response.find(
    ({ slot }) =&gt; slot === originalSlot.slot.padStart(5, 0)
  );

	if (!slotInfo) {
		return originalSlot;
	}

	return { ...originalSlot, ...slotInfo, slot: originalSlot.slot };
});

console.log(results);

<!-- end snippet -->

答案2

得分: 0

假设您更改response数组的插槽次数以匹配body的格式(如果您选择不这样做,可以使用@Aniket Raj在他的回答中使用的方法来比较时间):

您可以使用这个非常简单且自解释的方法:

let result = [...body];

for (let time of body) {
    let responseSlot = response.find(s => s.slot == time.slot);

    if (responseSlot) {
        result = [...result.filter(t => t != time), responseSlot];
    }
}

这将输出以下内容:

[
  { slot: '9:30',
    status: 'Available',
    clientName: '',
    doctorName: ''
  },
  { slot: '1:30',
    status: 'Available',
    clientName: '',
    doctorName: ''
  },
  {
    clientName: 'John Doe',
    doctorName: 'Paul Pierce',
    slot: '9:00',
    status: 'Not Available'
  },
  {
    clientName: 'James Bond',
    doctorName: 'Chris Paul',
    slot: '1:00',
    status: 'Not Available'
  }
]

这是您将response数组更改为以下内容:

const response = [{
    clientName: "John Doe",
    doctorName: "Paul Pierce",
    slot: "9:00",
    status: "Not Available"
}, {
    clientName: "James Bond",
    doctorName: "Chris Paul",
    slot: "1:00",
    status: "Not Available"
}]
英文:

Assuming you change the response array slot times to match the format of the body (if you choose not to this, you can use the method used by @Aniket Raj in his answer to compare the times):

You could use this very simple self-explanatory method:

let result = [...body];

for (let time of body) {
    let responseSlot = response.find(s =&gt; s.slot == time.slot);

    if (responseSlot) {
        result = [...result.filter(t =&gt; t != time), responseSlot];
    }
}

Which outputs the following:

[
  { slot: &#39;9:30&#39;,
    status: &#39;Available&#39;,
    clientName: &#39;&#39;,
    doctorName: &#39;&#39;
  },
  { slot: &#39;1:30&#39;,
    status: &#39;Available&#39;,
    clientName: &#39;&#39;,
    doctorName: &#39;&#39;
  },
  {
    clientName: &#39;John Doe&#39;,
    doctorName: &#39;Paul Pierce&#39;,
    slot: &#39;9:00&#39;,
    status: &#39;Not Available&#39;
  },
  {
    clientName: &#39;James Bond&#39;,
    doctorName: &#39;Chris Paul&#39;,
    slot: &#39;1:00&#39;,
    status: &#39;Not Available&#39;
  }
]

That is you change response array to this:

const response = [{
    clientName: &quot;John Doe&quot;,
    doctorName: &quot;Paul Pierce&quot;,
    slot: &quot;9:00&quot;,
    status: &quot;Not Available&quot;
}, {
    clientName: &quot;James Bond&quot;,
    doctorName: &quot;Chris Paul&quot;,
    slot: &quot;1:00&quot;,
    status: &quot;Not Available&quot;
}]

答案3

得分: 0

这里你可以尝试这个逻辑:

const first = [
  {
    slot: "9:00",
    status: "Available",
    clientName: "",
    doctorName: "",
  },
  {
    slot: "9:30",
    status: "Available",
    clientName: "",
    doctorName: "",
  },
  {
    slot: "1:00",
    status: "Available",
    clientName: "",
    doctorName: "",
  },
  {
    slot: "1:30",
    status: "Available",
    clientName: "",
    doctorName: "",
  },
];

const second = [
  {
    clientName: "John Doe",
    doctorName: "Paul Pierce",
    slot: "9:00",
    status: "Not Available",
  },
  {
    clientName: "James Bond",
    doctorName: "Chris Paul",
    slot: "1:00",
    status: "Not Available",
  },
];

// 用于解决09:01或9:01的问题
function timeStringChecker(timeStr) {
  let [leftStr, rightStr] = timeStr.split(":");
  return +(leftStr + rightStr);
}

first.forEach((elem) =>
  second.some((elem2) => {
    if (timeStringChecker(elem.slot) == timeStringChecker(elem2.slot)) {
      Object.assign(elem, elem2);
    }
  })
);

console.log(first);

希望对你有所帮助。

英文:

Here you can try this logic :

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const first = [
  {
    slot: &quot;9:00&quot;,
    status: &quot;Available&quot;,
    clientName: &quot;&quot;,
    doctorName: &quot;&quot;,
  },
  {
    slot: &quot;9:30&quot;,
    status: &quot;Available&quot;,
    clientName: &quot;&quot;,
    doctorName: &quot;&quot;,
  },
  {
    slot: &quot;1:00&quot;,
    status: &quot;Available&quot;,
    clientName: &quot;&quot;,
    doctorName: &quot;&quot;,
  },
  {
    slot: &quot;1:30&quot;,
    status: &quot;Available&quot;,
    clientName: &quot;&quot;,
    doctorName: &quot;&quot;,
  },
];

const second = [
  {
    clientName: &quot;John Doe&quot;,
    doctorName: &quot;Paul Pierce&quot;,
    slot: &quot;9:00&quot;,
    status: &quot;Not Available&quot;,
  },
  {
    clientName: &quot;James Bond&quot;,
    doctorName: &quot;Chris Paul&quot;,
    slot: &quot;1:00&quot;,
    status: &quot;Not Available&quot;,
  },
];

// To solve problem for 09:01 or 9:01
function timeStringChecker(timeStr) {
  let [leftStr, rightStr] = timeStr.split(&quot;:&quot;);
  return +(leftStr + rightStr);
}

first.forEach((elem) =&gt;
  second.some((elem2) =&gt; {
    if (timeStringChecker(elem.slot) == timeStringChecker(elem2.slot)) {
      Object.assign(elem, elem2);
    }
  })
);

console.log(first);

<!-- end snippet -->

答案4

得分: 0

以下是您要的代码翻译部分:

如前一帖所述这是您正在寻找的内容

const result = [];
Object.keys(body).forEach((key) =>
  key in response ? (result[key] = response[key]) : (result[key] = body[key])
);

这里的逻辑是您解析了 body 对象的所有属性如果属性值与 response 对象的属性值匹配它将覆盖 body 对象属性的值否则它将保留特定 body 对象的值

前一帖链接https://stackoverflow.com/questions/51206836/update-an-object-with-matching-properties-and-ignore-new-properties
英文:

As mentioned from a previous post this is what you are looking for:

const result = [];
Object.keys(body).forEach((key) =&gt;
  key in response ? (result[key] = response[key]) : (result[key] = body[key])
);

The logic here is that you parse all the properties of the body object and if the property value matched with the response object property value it will overwrite the value of the property for the body object. Otherwise it just keep the values of the specific body object as it is.

Link to previous post: https://stackoverflow.com/questions/51206836/update-an-object-with-matching-properties-and-ignore-new-properties

huangapple
  • 本文由 发表于 2023年3月12日 18:21:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/75712463.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定