问题描述
鉴于我有以下对象
{
"a": ["100","200"],"b": ["100"],"c": ["100","200","300"],"d": ["200"]
}
如何反转它,而不是成为值列表的键,而是对应键列表的值,就像这样:
{
"100": ["a","b","c"],"200": ["a","c","d"],"300": ["c"]
}
我尝试过_.reverse
,但实际上只是反转了键和值。
解决方法
使用Array.prototype.reduce
通过值缩小当前对象,并检查缩小的键数组中是否存在该键,如果不存在则添加它。
const obj = {
"a": ["100","200"],"b": ["100"],"c": ["100","200","300"],"d": ["200"]
};
const groupedResult = Object.entries(obj)
.reduce((r,[key,val]) => {
val.forEach((item) => {
if (!r[item]) {
r[item] = [key];
} else {
if (!r[item].includes(key)) {
r[item].push(key);
}
}
});
return r;
},Object.create(null));
console.log(groupedResult);
,
您可以使用 import React from 'react'
import io from 'socket.io-client'
import Peer from 'peerjs'
import './ClassWall.css'
import { Modal,Button } from 'antd';
import img from '../../uploads/349-3498013_laptop-personal-computer-diagram-computer-icons-download-laptop-clipart.png'
const socket = io.connect('http://localhost:4000/')
class LiveClass extends React.Component{
constructor(){
super()
this.state = {
userId :'',classStatus: '',videoSrc:'',visible: false
}
}
async componentDidMount(){
//set the user id of logedin user
const videoGrid = document.getElementById('video-grid')
const Myvideo = document.createElement('video')
Myvideo.addEventListener('click',()=>{
console.log(Myvideo)
})
Myvideo.muted = true
try {
const response = await fetch('http://localhost:4000/Auth//UserID/id',{
headers:{token:localStorage.token}
})
const Parse = await response.json()
this.setState({userId:Parse})
} catch (error) {
}
//get user id to connect through peer
const myPeer = new Peer(this.state.userId,{
host: '/',port:4001
})
//connect and share video stream
try {
const peers = {}
navigator.mediaDevices.getUserMedia({
video:true,audio:true
}).then(stream =>{
addVideoStream(Myvideo,stream)
myPeer.on('call',call=>{
call.answer(stream)
const video = document.createElement('video')
call.on('stream',userVideostream=>{
addVideoStream(video,userVideostream)
})
})
socket.on('user-connected',userId=>{
connectToNewUser(userId,stream)
console.log('newUser',userId)
})
})
socket.on('user-disconnect',userId=>{
if(peers[userId])peers[userId].close()
})
myPeer.on('open',id=>{
socket.emit('join-class',this.props.match.params.id,id)
})
//get user stream and connect
function connectToNewUser(userId,stream){
const call = myPeer.call(userId,stream)
const video = document.createElement('video')
video.setAttribute("class",`pointer`)
video.addEventListener('click',()=>{
console.log(video)
})
call.on('stream',userVideostream)
})
call.on('close',()=>{
video.remove()
})
peers[userId]=call
}
//Add video stream
function addVideoStream(video,stream){
const videoGrid = document.getElementById('video-grid')
video.srcObject = stream
video.addEventListener('loadedmetadata',() =>{
video.play()
})
videoGrid.append(video)
}
} catch (error) {
console.log('error',error)
}
this.checkIfClassTrue()
}
//check if its class
checkIfClassTrue = async()=>{
const response = await fetch(`http://localhost:4000/liveclass/${this.props.match.params.id}`)
const Parse = await response.json()
this.setState({classStatus:Parse})
}
//modal
showModal = () => {
this.setState({
visible: true,});
};
handleOk = e => {
console.log(e);
this.setState({
visible: false,});
};
handleCancel = e => {
console.log(e);
this.setState({
visible: false,});
};
render(){
return(
<div>
{
this.state.classStatus === 'Not found'?
'not found':
<div>
<div id="video-grid">
{/* <img src={img}/> */}
</div>
<Button type="primary" onClick={this.showModal}>
Open Modal
</Button>
<Modal
title="Basic Modal"
visible={this.state.visible}
onOk={this.handleOk}
onCancel={this.handleCancel}
>
</Modal>
</div>
}
</div>
)
}
}
export default LiveClass
和_.reduce()
_.forEach()
const data = {
a: ["100",b: ["100"],c: ["100",d: ["200"],}
const res = _.chain(data)
.reduce((result,value = [],key) => {
_.forEach(value,(v) => {
result[v] = [...(result[v] || []),key]
})
return result
},{})
.value()
console.log(JSON.stringify(res,null,2))
,
好吧,您可以向后减少它,以创建哈希作为结果,并保持更新。如果您在地图中找到该键(即您的值),请在地图中获取该键的值并添加当前键,否则创建一个空数组并添加当前键。
这是一个带有lodash的代码段(在lidash中,您可以直接在对象上应用_.reduce
。
let obj = {
"a": ["100","d": ["200"]
};
let res = _.reduce(obj,(r,e,k) => e.reduce((_,n) => (r[n] = (r[n] || [])).push(k) && r,r),{});
console.log(res);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js"></script>
好吧,现在我在这里使用了lodash,所以我可以直接在对象上应用reduce,否则您可以将其转换(对象输入)为条目,并在条目上应用普通JS reduce。因此,第一个reduce之前的代码将在此处稍作更改,请参见下面没有lodash的纯JS版本:
let obj = {
"a": ["100","d": ["200"]
};
let res = Object.entries(obj).reduce((r,[k,e]) => e.reduce((_,{});
console.log(res);