Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

javascript 数组项统计 #21

Open
ilezhi opened this issue May 11, 2018 · 2 comments
Open

javascript 数组项统计 #21

ilezhi opened this issue May 11, 2018 · 2 comments

Comments

@ilezhi
Copy link

ilezhi commented May 11, 2018

给定一个数组, 数组内的每一项都是一个数组, 并且有相同的长度. 写一个函数实现下面的转换.

exp 1
[
  ['a1', 'b1'],
  ['a1', 'b2'],
  ['a2', 'b3']
]
==> 
[
  {
    name: 'a1',
    sub: [
      {name: 'b1'},
      {name: 'b2'}
    ]
  },
  {
    name: 'a2'
    sub: [
      {name: 'b3'}
    ]
  }
]

exp 2

[
  ['a1', 'b1', 'c1'],
  ['a1', 'b1', 'c2'],
  ['a1', 'b2', 'c3'],
  ['a2', 'b3', 'c4'],
  ['a2', 'b4', 'c5']
]
==> 
[
  {
    name: 'a1',
    sub: [
      {
        name: 'b1',
        sub: [
          {name: 'c1'},
          {name: 'c2'}
        ]
      },
      {
        name: 'b2',
        sub: [
          {name: 'c3'}
        ]
      }
    ]
  },
  {
    name: 'a2',
    sub: [
      {
        name: 'b3',
        sub: [
          {name: 'c4'}
        ]
      },
      {
        name: 'b4',
        sub: [
          {name: 'c5'}
        ]
      }
    ]
  }
]

exp 3
[
  ['a1', 'b1', 'c1', 'd1'],
  ['a1', 'b1', 'c2', 'd2'],
  ['a1', 'b1', 'c2', 'd3'],
  ['a1', 'b2', 'c3', 'd4']
  ['a2', 'b3', 'c4', 'd5'],
  ['a2', 'b3', 'c4', 'd6']
  ['a2', 'b4', 'c5', 'd7'],
  ['a2', 'b4', 'c6', 'd8']
]
==> ?
@sunhengzhe
Copy link
Member

sunhengzhe commented May 11, 2018

查看输出:JSBIN

const data = [
  ['a1', 'b1', 'c1', 'd1'],
  ['a1', 'b1', 'c2', 'd2'],
  ['a1', 'b1', 'c2', 'd3'],
  ['a1', 'b2', 'c3', 'd4'],
  ['a2', 'b3', 'c4', 'd5'],
  ['a2', 'b3', 'c4', 'd6'],
  ['a2', 'b4', 'c5', 'd7'],
  ['a2', 'b4', 'c6', 'd8'],
];

function createRelation(arr) {
  const relationMap = {};

  arr.forEach(innerArr => {
    for (let i = 1; i < innerArr.length; i++) {
      const prev = innerArr[i - 1];
      const children = relationMap[prev];
      if (children) {
        if (!children.includes(innerArr[i])) {
          relationMap[prev].push(innerArr[i]);
        }
      } else {
        relationMap[prev] = [innerArr[i]];
      }
    }
  });
  
  return relationMap;
}

function createTree(arr, relationMap) {
  const createNode = name => {
    const node = { name };

    if (relationMap[name]) {
      node.sub = [];
      relationMap[name].forEach(child => {
        node.sub.push(createNode(child));
      })
    }
    
    return node;
  };
  
  const rst = [];
  const firstNodes = new Set();
  arr.forEach(arr => firstNodes.add(arr[0]));
  
  for (const node of firstNodes) {
    rst.push(createNode(node));
  }
  
  return rst;
}

const map = createRelation(data);
const tree = createTree(data, map);

console.log(JSON.stringify(tree));

@Jiasm
Copy link

Jiasm commented May 12, 2018

Online demo (open dev-tools console to see more)

(() => {
  function translate (arr) {
    return func(JSON.parse(JSON.stringify(arr)))
  }

  function func (arr) {
    return Object.values(arr.reduce((accumulator, currentValue) => {
      let name = currentValue.shift()
      let item = accumulator[name] = accumulator[name] || (currentValue.length ? {
        name,
        sub: []
      } : {name})

      item.sub && item.sub.push(currentValue)

      return accumulator
    }, {})).map(item => item.sub ? {
      ...item,
      sub: func(item.sub)
    } : item)
  }
  
  console.log('data:', JSON.stringify(translate(data), null, 2))
})()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants